adds vendor directory #36
34
glide.lock
generated
Normal file
34
glide.lock
generated
Normal file
@ -0,0 +1,34 @@
|
||||
hash: 70afc85692c35e634c2b935b6183e205c6c8a41a28dee9ec89af2bb01c932682
|
||||
updated: 2017-05-14T19:25:50.391136144-07:00
|
||||
imports:
|
||||
- name: github.com/couchbase/goutils
|
||||
version: 82b8055850965344f7d89d8a0abe364ac09dfa5e
|
||||
subpackages:
|
||||
- platform
|
||||
- name: github.com/jmoiron/sqlx
|
||||
version: d9bd385d68c068f1fabb5057e3dedcbcbb039d0f
|
||||
subpackages:
|
||||
- reflectx
|
||||
- name: github.com/mattn/go-gtk
|
||||
version: 4d185b2c694f34edad33988eddaf1314bfd9f132
|
||||
subpackages:
|
||||
- gdk
|
||||
- gdkpixbuf
|
||||
- glib
|
||||
- gtk
|
||||
- pango
|
||||
- name: github.com/mattn/go-pointer
|
||||
version: 46aacf851f34ad5bb503ee6d162915f3a5a5962c
|
||||
- name: github.com/mattn/go-sqlite3
|
||||
version: cf7286f069c3ef596efcc87781a4653a2e7607bd
|
||||
- name: github.com/therecipe/qt
|
||||
version: d0995a0002fadf7a6dc29ea85bffe3b0224757b6
|
||||
subpackages:
|
||||
- core
|
||||
- gui
|
||||
- widgets
|
||||
- name: golang.org/x/net
|
||||
version: 84f0e6f92b10139f986b1756e149a7d9de270cdc
|
||||
subpackages:
|
||||
- context
|
||||
testImports: []
|
17
glide.yaml
Normal file
17
glide.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
package: github.com/pztrn/urtrator
|
||||
import:
|
||||
- package: github.com/couchbase/goutils
|
||||
subpackages:
|
||||
- platform
|
||||
- package: github.com/jmoiron/sqlx
|
||||
- package: github.com/mattn/go-gtk
|
||||
subpackages:
|
||||
- gdk
|
||||
- gdkpixbuf
|
||||
- glib
|
||||
- gtk
|
||||
- package: github.com/mattn/go-sqlite3
|
||||
- package: github.com/therecipe/qt
|
||||
subpackages:
|
||||
- core
|
||||
- widgets
|
2
vendor/github.com/couchbase/goutils/.gitignore
generated
vendored
Normal file
2
vendor/github.com/couchbase/goutils/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*~
|
||||
*.swp
|
47
vendor/github.com/couchbase/goutils/LICENSE.md
generated
vendored
Normal file
47
vendor/github.com/couchbase/goutils/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
COUCHBASE INC. COMMUNITY EDITION LICENSE AGREEMENT
|
||||
|
||||
IMPORTANT-READ CAREFULLY: BY CLICKING THE "I ACCEPT" BOX OR INSTALLING,
|
||||
DOWNLOADING OR OTHERWISE USING THIS SOFTWARE AND ANY ASSOCIATED
|
||||
DOCUMENTATION, YOU, ON BEHALF OF YOURSELF OR AS AN AUTHORIZED
|
||||
REPRESENTATIVE ON BEHALF OF AN ENTITY ("LICENSEE") AGREE TO ALL THE
|
||||
TERMS OF THIS COMMUNITY EDITION LICENSE AGREEMENT (THE "AGREEMENT")
|
||||
REGARDING YOUR USE OF THE SOFTWARE. YOU REPRESENT AND WARRANT THAT YOU
|
||||
HAVE FULL LEGAL AUTHORITY TO BIND THE LICENSEE TO THIS AGREEMENT. IF YOU
|
||||
DO NOT AGREE WITH ALL OF THESE TERMS, DO NOT SELECT THE "I ACCEPT" BOX
|
||||
AND DO NOT INSTALL, DOWNLOAD OR OTHERWISE USE THE SOFTWARE. THE
|
||||
EFFECTIVE DATE OF THIS AGREEMENT IS THE DATE ON WHICH YOU CLICK "I
|
||||
ACCEPT" OR OTHERWISE INSTALL, DOWNLOAD OR USE THE SOFTWARE.
|
||||
|
||||
1. License Grant. Couchbase Inc. hereby grants Licensee, free of charge,
|
||||
the non-exclusive right to use, copy, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to Licensee including
|
||||
the following copyright notice in all copies or substantial portions of
|
||||
the Software:
|
||||
|
||||
Couchbase (r) http://www.Couchbase.com Copyright 2016 Couchbase, Inc.
|
||||
|
||||
As used in this Agreement, "Software" means the object code version of
|
||||
the applicable elastic data management server software provided by
|
||||
Couchbase Inc.
|
||||
|
||||
2. Restrictions. Licensee will not reverse engineer, disassemble, or
|
||||
decompile the Software (except to the extent such restrictions are
|
||||
prohibited by law).
|
||||
|
||||
3. Support. Couchbase, Inc. will provide Licensee with access to, and
|
||||
use of, the Couchbase, Inc. support forum available at the following
|
||||
URL: http://www.couchbase.org/forums/. Couchbase, Inc. may, at its
|
||||
discretion, modify, suspend or terminate support at any time upon notice
|
||||
to Licensee.
|
||||
|
||||
4. Warranty Disclaimer and Limitation of Liability. THE SOFTWARE IS
|
||||
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
COUCHBASE INC. OR THE AUTHORS OR COPYRIGHT HOLDERS IN THE SOFTWARE BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES (IINCLUDING, WITHOUT LIMITATION, DIRECT,
|
||||
INDIRECT OR CONSEQUENTIAL DAMAGES) OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
19
vendor/github.com/couchbase/goutils/README.md
generated
vendored
Normal file
19
vendor/github.com/couchbase/goutils/README.md
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# goutils
|
||||
Common utility libraries for Couchbase Go code.
|
||||
|
||||
* logging
|
||||
|
||||
Package logging implements a simple logging package. It defines a type,
|
||||
Logger, with methods for formatting output. The logger writes to standard out
|
||||
and prints the date and time in ISO 8601 standard with a timezone postfix
|
||||
of each logged message. The logger has option to log message as Json or
|
||||
Key-value or Text format.
|
||||
|
||||
* platform
|
||||
|
||||
Package platform implements common platform specific routines we often need
|
||||
in our Go applications.
|
||||
|
||||
## Installation
|
||||
|
||||
git clone git@github.com:couchbase/goutils.git
|
251
vendor/github.com/couchbase/goutils/go-cbaudit/audit_service.go
generated
vendored
Normal file
251
vendor/github.com/couchbase/goutils/go-cbaudit/audit_service.go
generated
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
// Copyright (c) 2016 Couchbase, Inc.
|
||||
// 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.
|
||||
package audit
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/couchbase/cbauth"
|
||||
"github.com/couchbase/go-couchbase"
|
||||
mc "github.com/couchbase/gomemcached"
|
||||
mcc "github.com/couchbase/gomemcached/client"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/couchbase/clog"
|
||||
)
|
||||
|
||||
// opcode for memcached audit command
|
||||
var AuditPutCommandCode = mc.CommandCode(0x27)
|
||||
|
||||
// write timeout
|
||||
var WriteTimeout = 1000 * time.Millisecond
|
||||
|
||||
// read timeout
|
||||
var ReadTimeout = 1000 * time.Millisecond
|
||||
var PoolClients = 5
|
||||
|
||||
type GenericFields struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
RealUserid RealUserId `json:"real_userid"`
|
||||
}
|
||||
|
||||
type RealUserId struct {
|
||||
Source string `json:"source"`
|
||||
Username string `json:"user"`
|
||||
}
|
||||
|
||||
type AuditSvc struct {
|
||||
uri string
|
||||
u string
|
||||
p string
|
||||
kvaddr string
|
||||
client chan *mcc.Client
|
||||
|
||||
m sync.Mutex // Protects the fields that follow.
|
||||
|
||||
initialized bool
|
||||
}
|
||||
|
||||
func NewAuditSvc(uri string) (*AuditSvc, error) {
|
||||
parsedUri, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u, p, err := cbauth.GetHTTPServiceAuth(parsedUri.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service := &AuditSvc{
|
||||
uri: uri,
|
||||
u: u,
|
||||
p: p,
|
||||
initialized: false,
|
||||
client: make(chan *mcc.Client, PoolClients),
|
||||
}
|
||||
// Attempt to initialize the service here. No need to check for
|
||||
// the err returned as if the service initialization were to
|
||||
// fail because of the server not being ready yet, we will do
|
||||
// this lazily when the Write API is invoked.
|
||||
service.init()
|
||||
log.Printf("audit: created new audit service")
|
||||
return service, nil
|
||||
}
|
||||
|
||||
func (service *AuditSvc) Write(eventId uint32, event interface{}) error {
|
||||
log.Printf("audit: Writing audit event. eventId=%v, event=%v\n", eventId,
|
||||
event)
|
||||
|
||||
err := service.init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := service.getClient()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if !client.IsHealthy() {
|
||||
newClient, err := GetNewConnection(service.kvaddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client = newClient
|
||||
}
|
||||
|
||||
defer service.releaseClient(client)
|
||||
return service.writeOnClient(client, eventId, event)
|
||||
}
|
||||
|
||||
func (service *AuditSvc) writeOnClient(client *mcc.Client, eventId uint32,
|
||||
event interface{}) error {
|
||||
req, err := composeAuditRequest(eventId, event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conn := client.Hijack()
|
||||
conn.(*net.TCPConn).SetWriteDeadline(time.Now().Add(WriteTimeout))
|
||||
|
||||
if err := client.Transmit(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn.(*net.TCPConn).SetReadDeadline(time.Now().Add(ReadTimeout))
|
||||
res, err := client.Receive()
|
||||
log.Printf("audit: response=%v, opcode=%v, opaque=%v, status=%v, err=%v\n",
|
||||
res, res.Opcode, res.Opaque, res.Status, err)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if res.Opcode != AuditPutCommandCode {
|
||||
return errors.New(fmt.Sprintf("unexpected #opcode %v", res.Opcode))
|
||||
} else if req.Opaque != res.Opaque {
|
||||
return errors.New(fmt.Sprintf("opaque mismatch, %v over %v",
|
||||
req.Opaque, res.Opaque))
|
||||
} else if res.Status != mc.SUCCESS {
|
||||
return errors.New(fmt.Sprintf("unsuccessful status = %v", res.Status))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func composeAuditRequest(eventId uint32, event interface{}) (
|
||||
*mc.MCRequest, error) {
|
||||
eventBytes, err := json.Marshal(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &mc.MCRequest{
|
||||
Opcode: AuditPutCommandCode}
|
||||
|
||||
req.Extras = make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(req.Extras[:4], eventId)
|
||||
|
||||
req.Body = eventBytes
|
||||
|
||||
req.Opaque = eventId
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (service *AuditSvc) init() error {
|
||||
service.m.Lock()
|
||||
defer service.m.Unlock()
|
||||
if !service.initialized {
|
||||
client, err := couchbase.ConnectWithAuthCreds(service.uri,
|
||||
service.u, service.p)
|
||||
if err != nil {
|
||||
log.Printf("audit :error in connecting to url %s err %v",
|
||||
service.uri, err)
|
||||
return err
|
||||
}
|
||||
pool, err := client.GetPool("default")
|
||||
if err != nil {
|
||||
log.Printf("audit :error in connecting to default pool %v", err)
|
||||
return err
|
||||
}
|
||||
for _, p := range pool.Nodes {
|
||||
if p.ThisNode {
|
||||
port, ok := p.Ports["direct"]
|
||||
if !ok {
|
||||
return fmt.Errorf("Error in getting memcached port")
|
||||
}
|
||||
h := strings.Split(p.Hostname, ":")
|
||||
if len(h) <= 1 {
|
||||
return fmt.Errorf("Invalid host string")
|
||||
}
|
||||
service.kvaddr = h[0] + ":" + strconv.Itoa(port)
|
||||
break
|
||||
}
|
||||
}
|
||||
if service.kvaddr == "" {
|
||||
return fmt.Errorf("Error in getting port")
|
||||
}
|
||||
for i := 0; i < PoolClients; i++ {
|
||||
c, err := GetNewConnection(service.kvaddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("audit: Error %v", err)
|
||||
}
|
||||
service.client <- c
|
||||
}
|
||||
service.initialized = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *AuditSvc) getClient() (*mcc.Client, error) {
|
||||
return <-service.client, nil
|
||||
}
|
||||
|
||||
func (service *AuditSvc) releaseClient(client *mcc.Client) error {
|
||||
service.client <- client
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetAuditBasicFields(req *http.Request) GenericFields {
|
||||
uid := getRealUserIdFromRequest(req)
|
||||
t := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
|
||||
return GenericFields{t, *uid}
|
||||
}
|
||||
|
||||
func getRealUserIdFromRequest(request *http.Request) *RealUserId {
|
||||
creds, err := cbauth.AuthWebCreds(request)
|
||||
if err != nil {
|
||||
log.Printf("Error getting real user id from http request."+
|
||||
" err=%v\n", err)
|
||||
// put unknown user in the audit log.
|
||||
return &RealUserId{"internal", "unknown"}
|
||||
}
|
||||
|
||||
return &RealUserId{creds.Domain(), creds.Name()}
|
||||
}
|
||||
|
||||
func GetNewConnection(kvAddr string) (*mcc.Client, error) {
|
||||
c, err := mcc.Connect("tcp", kvAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("audit: Error in connection to"+
|
||||
" memcached %v", err)
|
||||
}
|
||||
u, p, err := cbauth.GetMemcachedServiceAuth(kvAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("audit: Error in getting auth for"+
|
||||
" memcached %v", err)
|
||||
}
|
||||
_, err = c.Auth(u, p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("audit: Error in auth %v", err)
|
||||
}
|
||||
return c, nil
|
||||
}
|
481
vendor/github.com/couchbase/goutils/logging/logger.go
generated
vendored
Normal file
481
vendor/github.com/couchbase/goutils/logging/logger.go
generated
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
// Copyright (c) 2016 Couchbase, Inc.
|
||||
// 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.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Level int
|
||||
|
||||
const (
|
||||
NONE = Level(iota) // Disable all logging
|
||||
FATAL // System is in severe error state and has to abort
|
||||
SEVERE // System is in severe error state and cannot recover reliably
|
||||
ERROR // System is in error state but can recover and continue reliably
|
||||
WARN // System approaching error state, or is in a correct but undesirable state
|
||||
INFO // System-level events and status, in correct states
|
||||
REQUEST // Request-level events, with request-specific rlevel
|
||||
TRACE // Trace detailed system execution, e.g. function entry / exit
|
||||
DEBUG // Debug
|
||||
)
|
||||
|
||||
type LogEntryFormatter int
|
||||
|
||||
const (
|
||||
TEXTFORMATTER = LogEntryFormatter(iota)
|
||||
JSONFORMATTER
|
||||
KVFORMATTER
|
||||
)
|
||||
|
||||
func (level Level) String() string {
|
||||
return _LEVEL_NAMES[level]
|
||||
}
|
||||
|
||||
var _LEVEL_NAMES = []string{
|
||||
DEBUG: "DEBUG",
|
||||
TRACE: "TRACE",
|
||||
REQUEST: "REQUEST",
|
||||
INFO: "INFO",
|
||||
WARN: "WARN",
|
||||
ERROR: "ERROR",
|
||||
SEVERE: "SEVERE",
|
||||
FATAL: "FATAL",
|
||||
NONE: "NONE",
|
||||
}
|
||||
|
||||
var _LEVEL_MAP = map[string]Level{
|
||||
"debug": DEBUG,
|
||||
"trace": TRACE,
|
||||
"request": REQUEST,
|
||||
"info": INFO,
|
||||
"warn": WARN,
|
||||
"error": ERROR,
|
||||
"severe": SEVERE,
|
||||
"fatal": FATAL,
|
||||
"none": NONE,
|
||||
}
|
||||
|
||||
func ParseLevel(name string) (level Level, ok bool) {
|
||||
level, ok = _LEVEL_MAP[strings.ToLower(name)]
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Pair supports logging of key-value pairs. Keys beginning with _ are
|
||||
reserved for the logger, e.g. _time, _level, _msg, and _rlevel. The
|
||||
Pair APIs are designed to avoid heap allocation and garbage
|
||||
collection.
|
||||
|
||||
*/
|
||||
type Pairs []Pair
|
||||
type Pair struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Map allows key-value pairs to be specified using map literals or data
|
||||
structures. For example:
|
||||
|
||||
Errorm(msg, Map{...})
|
||||
|
||||
Map incurs heap allocation and garbage collection, so the Pair APIs
|
||||
should be preferred.
|
||||
|
||||
*/
|
||||
type Map map[string]interface{}
|
||||
|
||||
// Logger provides a common interface for logging libraries
|
||||
type Logger interface {
|
||||
/*
|
||||
These APIs write all the given pairs in addition to standard logger keys.
|
||||
*/
|
||||
Logp(level Level, msg string, kv ...Pair)
|
||||
|
||||
Debugp(msg string, kv ...Pair)
|
||||
|
||||
Tracep(msg string, kv ...Pair)
|
||||
|
||||
Requestp(rlevel Level, msg string, kv ...Pair)
|
||||
|
||||
Infop(msg string, kv ...Pair)
|
||||
|
||||
Warnp(msg string, kv ...Pair)
|
||||
|
||||
Errorp(msg string, kv ...Pair)
|
||||
|
||||
Severep(msg string, kv ...Pair)
|
||||
|
||||
Fatalp(msg string, kv ...Pair)
|
||||
|
||||
/*
|
||||
These APIs write the fields in the given kv Map in addition to standard logger keys.
|
||||
*/
|
||||
Logm(level Level, msg string, kv Map)
|
||||
|
||||
Debugm(msg string, kv Map)
|
||||
|
||||
Tracem(msg string, kv Map)
|
||||
|
||||
Requestm(rlevel Level, msg string, kv Map)
|
||||
|
||||
Infom(msg string, kv Map)
|
||||
|
||||
Warnm(msg string, kv Map)
|
||||
|
||||
Errorm(msg string, kv Map)
|
||||
|
||||
Severem(msg string, kv Map)
|
||||
|
||||
Fatalm(msg string, kv Map)
|
||||
|
||||
/*
|
||||
|
||||
These APIs only write _msg, _time, _level, and other logger keys. If
|
||||
the msg contains other fields, use the Pair or Map APIs instead.
|
||||
|
||||
*/
|
||||
Logf(level Level, fmt string, args ...interface{})
|
||||
|
||||
Debugf(fmt string, args ...interface{})
|
||||
|
||||
Tracef(fmt string, args ...interface{})
|
||||
|
||||
Requestf(rlevel Level, fmt string, args ...interface{})
|
||||
|
||||
Infof(fmt string, args ...interface{})
|
||||
|
||||
Warnf(fmt string, args ...interface{})
|
||||
|
||||
Errorf(fmt string, args ...interface{})
|
||||
|
||||
Severef(fmt string, args ...interface{})
|
||||
|
||||
Fatalf(fmt string, args ...interface{})
|
||||
|
||||
/*
|
||||
These APIs control the logging level
|
||||
*/
|
||||
|
||||
SetLevel(Level) // Set the logging level
|
||||
|
||||
Level() Level // Get the current logging level
|
||||
}
|
||||
|
||||
var logger Logger = nil
|
||||
var curLevel Level = DEBUG // initially set to never skip
|
||||
|
||||
var loggerMutex sync.RWMutex
|
||||
|
||||
// All the methods below first acquire the mutex (mostly in exclusive mode)
|
||||
// and only then check if logging at the current level is enabled.
|
||||
// This introduces a fair bottleneck for those log entries that should be
|
||||
// skipped (the majority, at INFO or below levels)
|
||||
// We try to predict here if we should lock the mutex at all by caching
|
||||
// the current log level: while dynamically changing logger, there might
|
||||
// be the odd entry skipped as the new level is cached.
|
||||
// Since we seem to never change the logger, this is not an issue.
|
||||
func skipLogging(level Level) bool {
|
||||
if logger == nil {
|
||||
return true
|
||||
}
|
||||
return level > curLevel
|
||||
}
|
||||
|
||||
func SetLogger(newLogger Logger) {
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger = newLogger
|
||||
if logger == nil {
|
||||
curLevel = NONE
|
||||
} else {
|
||||
curLevel = newLogger.Level()
|
||||
}
|
||||
}
|
||||
|
||||
func Logp(level Level, msg string, kv ...Pair) {
|
||||
if skipLogging(level) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Logp(level, msg, kv...)
|
||||
}
|
||||
|
||||
func Debugp(msg string, kv ...Pair) {
|
||||
if skipLogging(DEBUG) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Debugp(msg, kv...)
|
||||
}
|
||||
|
||||
func Tracep(msg string, kv ...Pair) {
|
||||
if skipLogging(TRACE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Tracep(msg, kv...)
|
||||
}
|
||||
|
||||
func Requestp(rlevel Level, msg string, kv ...Pair) {
|
||||
if skipLogging(REQUEST) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Requestp(rlevel, msg, kv...)
|
||||
}
|
||||
|
||||
func Infop(msg string, kv ...Pair) {
|
||||
if skipLogging(INFO) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Infop(msg, kv...)
|
||||
}
|
||||
|
||||
func Warnp(msg string, kv ...Pair) {
|
||||
if skipLogging(WARN) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Warnp(msg, kv...)
|
||||
}
|
||||
|
||||
func Errorp(msg string, kv ...Pair) {
|
||||
if skipLogging(ERROR) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Errorp(msg, kv...)
|
||||
}
|
||||
|
||||
func Severep(msg string, kv ...Pair) {
|
||||
if skipLogging(SEVERE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Severep(msg, kv...)
|
||||
}
|
||||
|
||||
func Fatalp(msg string, kv ...Pair) {
|
||||
if skipLogging(FATAL) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Fatalp(msg, kv...)
|
||||
}
|
||||
|
||||
func Logm(level Level, msg string, kv Map) {
|
||||
if skipLogging(level) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Logm(level, msg, kv)
|
||||
}
|
||||
|
||||
func Debugm(msg string, kv Map) {
|
||||
if skipLogging(DEBUG) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Debugm(msg, kv)
|
||||
}
|
||||
|
||||
func Tracem(msg string, kv Map) {
|
||||
if skipLogging(TRACE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Tracem(msg, kv)
|
||||
}
|
||||
|
||||
func Requestm(rlevel Level, msg string, kv Map) {
|
||||
if skipLogging(REQUEST) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Requestm(rlevel, msg, kv)
|
||||
}
|
||||
|
||||
func Infom(msg string, kv Map) {
|
||||
if skipLogging(INFO) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Infom(msg, kv)
|
||||
}
|
||||
|
||||
func Warnm(msg string, kv Map) {
|
||||
if skipLogging(WARN) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Warnm(msg, kv)
|
||||
}
|
||||
|
||||
func Errorm(msg string, kv Map) {
|
||||
if skipLogging(ERROR) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Errorm(msg, kv)
|
||||
}
|
||||
|
||||
func Severem(msg string, kv Map) {
|
||||
if skipLogging(SEVERE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Severem(msg, kv)
|
||||
}
|
||||
|
||||
func Fatalm(msg string, kv Map) {
|
||||
if skipLogging(FATAL) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Fatalm(msg, kv)
|
||||
}
|
||||
|
||||
func Logf(level Level, fmt string, args ...interface{}) {
|
||||
if skipLogging(level) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Logf(level, fmt, args...)
|
||||
}
|
||||
|
||||
func Debugf(fmt string, args ...interface{}) {
|
||||
if skipLogging(DEBUG) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Debugf(fmt, args...)
|
||||
}
|
||||
|
||||
func Tracef(fmt string, args ...interface{}) {
|
||||
if skipLogging(TRACE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Tracef(fmt, args...)
|
||||
}
|
||||
|
||||
func Requestf(rlevel Level, fmt string, args ...interface{}) {
|
||||
if skipLogging(REQUEST) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Requestf(rlevel, fmt, args...)
|
||||
}
|
||||
|
||||
func Infof(fmt string, args ...interface{}) {
|
||||
if skipLogging(INFO) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Infof(fmt, args...)
|
||||
}
|
||||
|
||||
func Warnf(fmt string, args ...interface{}) {
|
||||
if skipLogging(WARN) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Warnf(fmt, args...)
|
||||
}
|
||||
|
||||
func Errorf(fmt string, args ...interface{}) {
|
||||
if skipLogging(ERROR) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Errorf(fmt, args...)
|
||||
}
|
||||
|
||||
func Severef(fmt string, args ...interface{}) {
|
||||
if skipLogging(SEVERE) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Severef(fmt, args...)
|
||||
}
|
||||
|
||||
func Fatalf(fmt string, args ...interface{}) {
|
||||
if skipLogging(FATAL) {
|
||||
return
|
||||
}
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Fatalf(fmt, args...)
|
||||
}
|
||||
|
||||
func SetLevel(level Level) {
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.SetLevel(level)
|
||||
curLevel = level
|
||||
}
|
||||
|
||||
func LogLevel() Level {
|
||||
loggerMutex.RLock()
|
||||
defer loggerMutex.RUnlock()
|
||||
return logger.Level()
|
||||
}
|
||||
|
||||
func Stackf(level Level, fmt string, args ...interface{}) {
|
||||
if skipLogging(level) {
|
||||
return
|
||||
}
|
||||
buf := make([]byte, 1<<16)
|
||||
n := runtime.Stack(buf, false)
|
||||
s := string(buf[0:n])
|
||||
loggerMutex.Lock()
|
||||
defer loggerMutex.Unlock()
|
||||
logger.Logf(level, fmt, args...)
|
||||
logger.Logf(level, s)
|
||||
}
|
||||
|
||||
func init() {
|
||||
logger = NewLogger(os.Stderr, INFO, KVFORMATTER)
|
||||
SetLogger(logger)
|
||||
}
|
318
vendor/github.com/couchbase/goutils/logging/logger_golog.go
generated
vendored
Normal file
318
vendor/github.com/couchbase/goutils/logging/logger_golog.go
generated
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
// Copyright (c) 2016 Couchbase, Inc.
|
||||
// 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.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type goLogger struct {
|
||||
logger *log.Logger
|
||||
level Level
|
||||
entryFormatter formatter
|
||||
}
|
||||
|
||||
const (
|
||||
_LEVEL = "_level"
|
||||
_MSG = "_msg"
|
||||
_TIME = "_time"
|
||||
_RLEVEL = "_rlevel"
|
||||
)
|
||||
|
||||
func NewLogger(out io.Writer, lvl Level, fmtLogging LogEntryFormatter) *goLogger {
|
||||
logger := &goLogger{
|
||||
logger: log.New(out, "", 0),
|
||||
level: lvl,
|
||||
}
|
||||
if fmtLogging == JSONFORMATTER {
|
||||
logger.entryFormatter = &jsonFormatter{}
|
||||
} else if fmtLogging == KVFORMATTER {
|
||||
logger.entryFormatter = &keyvalueFormatter{}
|
||||
} else {
|
||||
logger.entryFormatter = &textFormatter{}
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
func (gl *goLogger) Logp(level Level, msg string, kv ...Pair) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if level <= gl.level {
|
||||
e := newLogEntry(msg, level)
|
||||
copyPairs(e, kv)
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Debugp(msg string, kv ...Pair) {
|
||||
gl.Logp(DEBUG, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Tracep(msg string, kv ...Pair) {
|
||||
gl.Logp(TRACE, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Requestp(rlevel Level, msg string, kv ...Pair) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if REQUEST <= gl.level {
|
||||
e := newLogEntry(msg, REQUEST)
|
||||
e.Rlevel = rlevel
|
||||
copyPairs(e, kv)
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Infop(msg string, kv ...Pair) {
|
||||
gl.Logp(INFO, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Warnp(msg string, kv ...Pair) {
|
||||
gl.Logp(WARN, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Errorp(msg string, kv ...Pair) {
|
||||
gl.Logp(ERROR, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Severep(msg string, kv ...Pair) {
|
||||
gl.Logp(SEVERE, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Fatalp(msg string, kv ...Pair) {
|
||||
gl.Logp(FATAL, msg, kv...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Logm(level Level, msg string, kv Map) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if level <= gl.level {
|
||||
e := newLogEntry(msg, level)
|
||||
e.Data = kv
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Debugm(msg string, kv Map) {
|
||||
gl.Logm(DEBUG, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Tracem(msg string, kv Map) {
|
||||
gl.Logm(TRACE, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Requestm(rlevel Level, msg string, kv Map) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if REQUEST <= gl.level {
|
||||
e := newLogEntry(msg, REQUEST)
|
||||
e.Rlevel = rlevel
|
||||
e.Data = kv
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Infom(msg string, kv Map) {
|
||||
gl.Logm(INFO, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Warnm(msg string, kv Map) {
|
||||
gl.Logm(WARN, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Errorm(msg string, kv Map) {
|
||||
gl.Logm(ERROR, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Severem(msg string, kv Map) {
|
||||
gl.Logm(SEVERE, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Fatalm(msg string, kv Map) {
|
||||
gl.Logm(FATAL, msg, kv)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Logf(level Level, format string, args ...interface{}) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if level <= gl.level {
|
||||
e := newLogEntry(fmt.Sprintf(format, args...), level)
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Debugf(format string, args ...interface{}) {
|
||||
gl.Logf(DEBUG, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Tracef(format string, args ...interface{}) {
|
||||
gl.Logf(TRACE, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Requestf(rlevel Level, format string, args ...interface{}) {
|
||||
if gl.logger == nil {
|
||||
return
|
||||
}
|
||||
if REQUEST <= gl.level {
|
||||
e := newLogEntry(fmt.Sprintf(format, args...), REQUEST)
|
||||
e.Rlevel = rlevel
|
||||
gl.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (gl *goLogger) Infof(format string, args ...interface{}) {
|
||||
gl.Logf(INFO, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Warnf(format string, args ...interface{}) {
|
||||
gl.Logf(WARN, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Errorf(format string, args ...interface{}) {
|
||||
gl.Logf(ERROR, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Severef(format string, args ...interface{}) {
|
||||
gl.Logf(SEVERE, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Fatalf(format string, args ...interface{}) {
|
||||
gl.Logf(FATAL, format, args...)
|
||||
}
|
||||
|
||||
func (gl *goLogger) Level() Level {
|
||||
return gl.level
|
||||
}
|
||||
|
||||
func (gl *goLogger) SetLevel(level Level) {
|
||||
gl.level = level
|
||||
}
|
||||
|
||||
func (gl *goLogger) log(newEntry *logEntry) {
|
||||
s := gl.entryFormatter.format(newEntry)
|
||||
gl.logger.Print(s)
|
||||
}
|
||||
|
||||
type logEntry struct {
|
||||
Time string
|
||||
Level Level
|
||||
Rlevel Level
|
||||
Message string
|
||||
Data Map
|
||||
}
|
||||
|
||||
func newLogEntry(msg string, level Level) *logEntry {
|
||||
return &logEntry{
|
||||
Time: time.Now().Format("2006-01-02T15:04:05.000-07:00"), // time.RFC3339 with milliseconds
|
||||
Level: level,
|
||||
Rlevel: NONE,
|
||||
Message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
func copyPairs(newEntry *logEntry, pairs []Pair) {
|
||||
newEntry.Data = make(Map, len(pairs))
|
||||
for _, p := range pairs {
|
||||
newEntry.Data[p.Name] = p.Value
|
||||
}
|
||||
}
|
||||
|
||||
type formatter interface {
|
||||
format(*logEntry) string
|
||||
}
|
||||
|
||||
type textFormatter struct {
|
||||
}
|
||||
|
||||
// ex. 2016-02-10T09:15:25.498-08:00 [INFO] This is a message from test in text format
|
||||
|
||||
func (*textFormatter) format(newEntry *logEntry) string {
|
||||
b := &bytes.Buffer{}
|
||||
appendValue(b, newEntry.Time)
|
||||
if newEntry.Rlevel != NONE {
|
||||
fmt.Fprintf(b, "[%s,%s] ", newEntry.Level.String(), newEntry.Rlevel.String())
|
||||
} else {
|
||||
fmt.Fprintf(b, "[%s] ", newEntry.Level.String())
|
||||
}
|
||||
appendValue(b, newEntry.Message)
|
||||
for key, value := range newEntry.Data {
|
||||
appendKeyValue(b, key, value)
|
||||
}
|
||||
b.WriteByte('\n')
|
||||
s := bytes.NewBuffer(b.Bytes())
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func appendValue(b *bytes.Buffer, value interface{}) {
|
||||
if _, ok := value.(string); ok {
|
||||
fmt.Fprintf(b, "%s ", value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v ", value)
|
||||
}
|
||||
}
|
||||
|
||||
type keyvalueFormatter struct {
|
||||
}
|
||||
|
||||
// ex. _time=2016-02-10T09:15:25.498-08:00 _level=INFO _msg=This is a message from test in key-value format
|
||||
|
||||
func (*keyvalueFormatter) format(newEntry *logEntry) string {
|
||||
b := &bytes.Buffer{}
|
||||
appendKeyValue(b, _TIME, newEntry.Time)
|
||||
appendKeyValue(b, _LEVEL, newEntry.Level.String())
|
||||
if newEntry.Rlevel != NONE {
|
||||
appendKeyValue(b, _RLEVEL, newEntry.Rlevel.String())
|
||||
}
|
||||
appendKeyValue(b, _MSG, newEntry.Message)
|
||||
for key, value := range newEntry.Data {
|
||||
appendKeyValue(b, key, value)
|
||||
}
|
||||
b.WriteByte('\n')
|
||||
s := bytes.NewBuffer(b.Bytes())
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func appendKeyValue(b *bytes.Buffer, key, value interface{}) {
|
||||
if _, ok := value.(string); ok {
|
||||
fmt.Fprintf(b, "%v=%s ", key, value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v=%v ", key, value)
|
||||
}
|
||||
}
|
||||
|
||||
type jsonFormatter struct {
|
||||
}
|
||||
|
||||
// ex. {"_level":"INFO","_msg":"This is a message from test in json format","_time":"2016-02-10T09:12:59.518-08:00"}
|
||||
|
||||
func (*jsonFormatter) format(newEntry *logEntry) string {
|
||||
if newEntry.Data == nil {
|
||||
newEntry.Data = make(Map, 5)
|
||||
}
|
||||
newEntry.Data[_TIME] = newEntry.Time
|
||||
newEntry.Data[_LEVEL] = newEntry.Level.String()
|
||||
if newEntry.Rlevel != NONE {
|
||||
newEntry.Data[_RLEVEL] = newEntry.Rlevel.String()
|
||||
}
|
||||
newEntry.Data[_MSG] = newEntry.Message
|
||||
serialized, _ := json.Marshal(newEntry.Data)
|
||||
s := bytes.NewBuffer(append(serialized, '\n'))
|
||||
return s.String()
|
||||
}
|
236
vendor/github.com/couchbase/goutils/logging/logger_golog_test.go
generated
vendored
Normal file
236
vendor/github.com/couchbase/goutils/logging/logger_golog_test.go
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
// Copyright (c) 2016 Couchbase, Inc.
|
||||
// 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.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var buffer *bytes.Buffer
|
||||
|
||||
func setLogWriter(w io.Writer, lvl Level, fmtLogging LogEntryFormatter) {
|
||||
logger = NewLogger(w, lvl, fmtLogging)
|
||||
SetLogger(logger)
|
||||
}
|
||||
|
||||
func TestStub(t *testing.T) {
|
||||
logger := NewLogger(os.Stdout, DEBUG, KVFORMATTER)
|
||||
SetLogger(logger)
|
||||
|
||||
logger.Infof("This is a message from %s", "test")
|
||||
Infof("This is a message from %s", "test")
|
||||
logger.Infop("This is a message from ", Pair{"name", "test"}, Pair{"Queue Size", 10}, Pair{"Debug Mode", false})
|
||||
Infop("This is a message from ", Pair{"name", "test"})
|
||||
|
||||
logger.Infom("This is a message from ", Map{"name": "test", "Queue Size": 10, "Debug Mode": false})
|
||||
Infom("This is a message from ", Map{"name": "test"})
|
||||
|
||||
logger.Requestf(WARN, "This is a Request from %s", "test")
|
||||
Requestf(INFO, "This is a Request from %s", "test")
|
||||
logger.Requestp(DEBUG, "This is a Request from ", Pair{"name", "test"})
|
||||
Requestp(ERROR, "This is a Request from ", Pair{"name", "test"})
|
||||
|
||||
logger.SetLevel(WARN)
|
||||
fmt.Printf("Log level is %s\n", logger.Level())
|
||||
|
||||
logger.Requestf(WARN, "This is a Request from %s", "test")
|
||||
Requestf(INFO, "This is a Request from %s", "test")
|
||||
logger.Requestp(DEBUG, "This is a Request from ", Pair{"name", "test"})
|
||||
Requestp(ERROR, "This is a Request from ", Pair{"name", "test"})
|
||||
|
||||
logger.Warnf("This is a message from %s", "test")
|
||||
Infof("This is a message from %s", "test")
|
||||
logger.Debugp("This is a message from ", Pair{"name", "test"})
|
||||
Errorp("This is a message from ", Pair{"name", "test"})
|
||||
|
||||
fmt.Printf("Changing to json formatter\n")
|
||||
logger.entryFormatter = &jsonFormatter{}
|
||||
logger.SetLevel(DEBUG)
|
||||
|
||||
logger.Infof("This is a message from %s", "test")
|
||||
Infof("This is a message from %s", "test")
|
||||
logger.Infop("This is a message from ", Pair{"name", "test"}, Pair{"Queue Size", 10}, Pair{"Debug Mode", false})
|
||||
Infop("This is a message from ", Pair{"name", "test"})
|
||||
|
||||
logger.Infom("This is a message from ", Map{"name": "test", "Queue Size": 10, "Debug Mode": false})
|
||||
Infom("This is a message from ", Map{"name": "test"})
|
||||
|
||||
logger.Requestf(WARN, "This is a Request from %s", "test")
|
||||
Requestf(INFO, "This is a Request from %s", "test")
|
||||
logger.Requestp(DEBUG, "This is a Request from ", Pair{"name", "test"})
|
||||
Requestp(ERROR, "This is a Request from ", Pair{"name", "test"})
|
||||
|
||||
fmt.Printf("Changing to Text formatter\n")
|
||||
logger.entryFormatter = &textFormatter{}
|
||||
logger.SetLevel(DEBUG)
|
||||
|
||||
logger.Infof("This is a message from %s", "test")
|
||||
Infof("This is a message from %s", "test")
|
||||
logger.Infop("This is a message from ", Pair{"name", "test"}, Pair{"Queue Size", 10}, Pair{"Debug Mode", false})
|
||||
Infop("This is a message from ", Pair{"name", "test"})
|
||||
|
||||
logger.Infom("This is a message from ", Map{"name": "test", "Queue Size": 10, "Debug Mode": false})
|
||||
Infom("This is a message from ", Map{"name": "test"})
|
||||
|
||||
logger.Requestf(WARN, "This is a Request from %s", "test")
|
||||
Requestf(INFO, "This is a Request from %s", "test")
|
||||
logger.Requestp(DEBUG, "This is a Request from ", Pair{"name", "test"})
|
||||
Requestp(ERROR, "This is a Request from ", Pair{"name", "test"})
|
||||
|
||||
buffer.Reset()
|
||||
logger = NewLogger(buffer, DEBUG, KVFORMATTER)
|
||||
logger.Infof("This is a message from test in key-value format")
|
||||
if s := string(buffer.Bytes()); strings.Contains(s, "_msg=This is a message from test in key-value format") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
}
|
||||
buffer.Reset()
|
||||
logger.entryFormatter = &jsonFormatter{}
|
||||
logger.Infof("This is a message from test in jason format")
|
||||
if s := string(buffer.Bytes()); strings.Contains(s, "\"_msg\":\"This is a message from test in jason format\"") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
}
|
||||
buffer.Reset()
|
||||
logger.entryFormatter = &textFormatter{}
|
||||
logger.Infof("This is a message from test in text format")
|
||||
if s := string(buffer.Bytes()); strings.Contains(s, "[INFO] This is a message from test in text format") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
buffer = bytes.NewBuffer([]byte{})
|
||||
buffer.Reset()
|
||||
}
|
||||
|
||||
func TestLogNone(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, DEBUG, KVFORMATTER)
|
||||
Warnf("%s", "test")
|
||||
if s := string(buffer.Bytes()); strings.Contains(s, "test") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
}
|
||||
SetLevel(NONE)
|
||||
Warnf("test")
|
||||
if s := string(buffer.Bytes()); s == "" {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
}
|
||||
}
|
||||
func TestLogLevelDefault(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, INFO, KVFORMATTER)
|
||||
SetLevel(INFO)
|
||||
Warnf("%s", "warn")
|
||||
Errorf("error")
|
||||
Severef("severe")
|
||||
Infof("info")
|
||||
Debugf("debug")
|
||||
Tracef("trace")
|
||||
s := string(buffer.Bytes())
|
||||
if strings.Contains(s, "warn") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
} else if strings.Contains(s, "error") == false {
|
||||
t.Errorf("Errorf() failed %v", s)
|
||||
} else if strings.Contains(s, "severe") == false {
|
||||
t.Errorf("Severef() failed %v", s)
|
||||
} else if strings.Contains(s, "info") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
} else if strings.Contains(s, "debug") == true {
|
||||
t.Errorf("Debugf() failed %v", s)
|
||||
} else if strings.Contains(s, "trace") == true {
|
||||
t.Errorf("Tracef() failed %v", s)
|
||||
}
|
||||
setLogWriter(os.Stdout, INFO, KVFORMATTER)
|
||||
}
|
||||
|
||||
func TestLogLevelInfo(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, INFO, KVFORMATTER)
|
||||
Warnf("warn")
|
||||
Infof("info")
|
||||
Debugf("debug")
|
||||
Tracef("trace")
|
||||
s := string(buffer.Bytes())
|
||||
if strings.Contains(s, "warn") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
} else if strings.Contains(s, "info") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
} else if strings.Contains(s, "debug") == true {
|
||||
t.Errorf("Debugf() failed %v", s)
|
||||
} else if strings.Contains(s, "trace") == true {
|
||||
t.Errorf("Tracef() failed %v", s)
|
||||
}
|
||||
setLogWriter(os.Stdout, INFO, KVFORMATTER)
|
||||
}
|
||||
|
||||
func TestLogLevelDebug(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, DEBUG, KVFORMATTER)
|
||||
Warnf("warn")
|
||||
Infof("info")
|
||||
Debugf("debug")
|
||||
Tracef("trace")
|
||||
s := string(buffer.Bytes())
|
||||
if strings.Contains(s, "warn") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
} else if strings.Contains(s, "info") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
} else if strings.Contains(s, "debug") == false {
|
||||
t.Errorf("Debugf() failed %v", s)
|
||||
} else if strings.Contains(s, "trace") == false {
|
||||
t.Errorf("Tracef() failed %v", s)
|
||||
}
|
||||
setLogWriter(os.Stdout, INFO, KVFORMATTER)
|
||||
}
|
||||
|
||||
func TestLogLevelTrace(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, TRACE, KVFORMATTER)
|
||||
Warnf("warn")
|
||||
Infof("info")
|
||||
Debugf("debug")
|
||||
Tracef("trace")
|
||||
s := string(buffer.Bytes())
|
||||
if strings.Contains(s, "warn") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
} else if strings.Contains(s, "info") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
} else if strings.Contains(s, "debug") == true {
|
||||
t.Errorf("Debugf() failed %v", s)
|
||||
} else if strings.Contains(s, "trace") == false {
|
||||
t.Errorf("Tracef() failed %v", s)
|
||||
}
|
||||
setLogWriter(os.Stdout, INFO, KVFORMATTER)
|
||||
}
|
||||
|
||||
func TestDefaultLog(t *testing.T) {
|
||||
buffer.Reset()
|
||||
setLogWriter(buffer, TRACE, KVFORMATTER)
|
||||
sl := logger
|
||||
sl.Warnf("warn")
|
||||
sl.Infof("info")
|
||||
sl.Debugf("debug")
|
||||
sl.Tracef("trace")
|
||||
s := string(buffer.Bytes())
|
||||
if strings.Contains(s, "warn") == false {
|
||||
t.Errorf("Warnf() failed %v", s)
|
||||
} else if strings.Contains(s, "info") == false {
|
||||
t.Errorf("Infof() failed %v", s)
|
||||
} else if strings.Contains(s, "trace") == false {
|
||||
t.Errorf("Tracef() failed %v", s)
|
||||
} else if strings.Contains(s, "debug") == true {
|
||||
t.Errorf("Debugf() failed %v", s)
|
||||
}
|
||||
setLogWriter(os.Stdout, INFO, KVFORMATTER)
|
||||
}
|
15
vendor/github.com/couchbase/goutils/platform/console.go
generated
vendored
Normal file
15
vendor/github.com/couchbase/goutils/platform/console.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2016 Couchbase, Inc.
|
||||
// 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 !windows
|
||||
|
||||
package platform
|
||||
|
||||
func HideConsole(_ bool) {
|
||||
}
|
33
vendor/github.com/couchbase/goutils/platform/console_windows.go
generated
vendored
Normal file
33
vendor/github.com/couchbase/goutils/platform/console_windows.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2013 Couchbase, Inc.
|
||||
// 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 windows
|
||||
|
||||
package platform
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Hide console on windows without removing it unlike -H windowsgui.
|
||||
func HideConsole(hide bool) {
|
||||
var k32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
var cw = k32.NewProc("GetConsoleWindow")
|
||||
var u32 = syscall.NewLazyDLL("user32.dll")
|
||||
var sw = u32.NewProc("ShowWindow")
|
||||
hwnd, _, _ := cw.Call()
|
||||
if hwnd == 0 {
|
||||
return
|
||||
}
|
||||
if hide {
|
||||
var SW_HIDE uintptr = 0
|
||||
sw.Call(hwnd, SW_HIDE)
|
||||
} else {
|
||||
var SW_RESTORE uintptr = 9
|
||||
sw.Call(hwnd, SW_RESTORE)
|
||||
}
|
||||
}
|
24
vendor/github.com/jmoiron/sqlx/.gitignore
generated
vendored
Normal file
24
vendor/github.com/jmoiron/sqlx/.gitignore
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
tags
|
||||
environ
|
23
vendor/github.com/jmoiron/sqlx/LICENSE
generated
vendored
Normal file
23
vendor/github.com/jmoiron/sqlx/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright (c) 2013, Jason Moiron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
183
vendor/github.com/jmoiron/sqlx/README.md
generated
vendored
Normal file
183
vendor/github.com/jmoiron/sqlx/README.md
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
# sqlx
|
||||
|
||||
[![Build Status](https://drone.io/github.com/jmoiron/sqlx/status.png)](https://drone.io/github.com/jmoiron/sqlx/latest) [![Godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/jmoiron/sqlx) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/jmoiron/sqlx/master/LICENSE)
|
||||
|
||||
sqlx is a library which provides a set of extensions on go's standard
|
||||
`database/sql` library. The sqlx versions of `sql.DB`, `sql.TX`, `sql.Stmt`,
|
||||
et al. all leave the underlying interfaces untouched, so that their interfaces
|
||||
are a superset on the standard ones. This makes it relatively painless to
|
||||
integrate existing codebases using database/sql with sqlx.
|
||||
|
||||
Major additional concepts are:
|
||||
|
||||
* Marshal rows into structs (with embedded struct support), maps, and slices
|
||||
* Named parameter support including prepared statements
|
||||
* `Get` and `Select` to go quickly from query to struct/slice
|
||||
|
||||
In addition to the [godoc API documentation](http://godoc.org/github.com/jmoiron/sqlx),
|
||||
there is also some [standard documentation](http://jmoiron.github.io/sqlx/) that
|
||||
explains how to use `database/sql` along with sqlx.
|
||||
|
||||
## Recent Changes
|
||||
|
||||
* sqlx/types.JsonText has been renamed to JSONText to follow Go naming conventions.
|
||||
|
||||
This breaks backwards compatibility, but it's in a way that is trivially fixable
|
||||
(`s/JsonText/JSONText/g`). The `types` package is both experimental and not in
|
||||
active development currently.
|
||||
|
||||
* Using Go 1.6 and below with `types.JSONText` and `types.GzippedText` can be _potentially unsafe_, **especially** when used with common auto-scan sqlx idioms like `Select` and `Get`. See [golang bug #13905](https://github.com/golang/go/issues/13905).
|
||||
|
||||
### Backwards Compatibility
|
||||
|
||||
There is no Go1-like promise of absolute stability, but I take the issue seriously
|
||||
and will maintain the library in a compatible state unless vital bugs prevent me
|
||||
from doing so. Since [#59](https://github.com/jmoiron/sqlx/issues/59) and
|
||||
[#60](https://github.com/jmoiron/sqlx/issues/60) necessitated breaking behavior,
|
||||
a wider API cleanup was done at the time of fixing. It's possible this will happen
|
||||
in future; if it does, a git tag will be provided for users requiring the old
|
||||
behavior to continue to use it until such a time as they can migrate.
|
||||
|
||||
## install
|
||||
|
||||
go get github.com/jmoiron/sqlx
|
||||
|
||||
## issues
|
||||
|
||||
Row headers can be ambiguous (`SELECT 1 AS a, 2 AS a`), and the result of
|
||||
`Columns()` does not fully qualify column names in queries like:
|
||||
|
||||
```sql
|
||||
SELECT a.id, a.name, b.id, b.name FROM foos AS a JOIN foos AS b ON a.parent = b.id;
|
||||
```
|
||||
|
||||
making a struct or map destination ambiguous. Use `AS` in your queries
|
||||
to give columns distinct names, `rows.Scan` to scan them manually, or
|
||||
`SliceScan` to get a slice of results.
|
||||
|
||||
## usage
|
||||
|
||||
Below is an example which shows some common use cases for sqlx. Check
|
||||
[sqlx_test.go](https://github.com/jmoiron/sqlx/blob/master/sqlx_test.go) for more
|
||||
usage.
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/lib/pq"
|
||||
"database/sql"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"log"
|
||||
)
|
||||
|
||||
var schema = `
|
||||
CREATE TABLE person (
|
||||
first_name text,
|
||||
last_name text,
|
||||
email text
|
||||
);
|
||||
|
||||
CREATE TABLE place (
|
||||
country text,
|
||||
city text NULL,
|
||||
telcode integer
|
||||
)`
|
||||
|
||||
type Person struct {
|
||||
FirstName string `db:"first_name"`
|
||||
LastName string `db:"last_name"`
|
||||
Email string
|
||||
}
|
||||
|
||||
type Place struct {
|
||||
Country string
|
||||
City sql.NullString
|
||||
TelCode int
|
||||
}
|
||||
|
||||
func main() {
|
||||
// this Pings the database trying to connect, panics on error
|
||||
// use sqlx.Open() for sql.Open() semantics
|
||||
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// exec the schema or fail; multi-statement Exec behavior varies between
|
||||
// database drivers; pq will exec them all, sqlite3 won't, ymmv
|
||||
db.MustExec(schema)
|
||||
|
||||
tx := db.MustBegin()
|
||||
tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "jmoiron@jmoiron.net")
|
||||
tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "John", "Doe", "johndoeDNE@gmail.net")
|
||||
tx.MustExec("INSERT INTO place (country, city, telcode) VALUES ($1, $2, $3)", "United States", "New York", "1")
|
||||
tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Hong Kong", "852")
|
||||
tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Singapore", "65")
|
||||
// Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person
|
||||
tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "jane.citzen@example.com"})
|
||||
tx.Commit()
|
||||
|
||||
// Query the database, storing results in a []Person (wrapped in []interface{})
|
||||
people := []Person{}
|
||||
db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC")
|
||||
jason, john := people[0], people[1]
|
||||
|
||||
fmt.Printf("%#v\n%#v", jason, john)
|
||||
// Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"}
|
||||
// Person{FirstName:"John", LastName:"Doe", Email:"johndoeDNE@gmail.net"}
|
||||
|
||||
// You can also get a single result, a la QueryRow
|
||||
jason = Person{}
|
||||
err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
|
||||
fmt.Printf("%#v\n", jason)
|
||||
// Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"}
|
||||
|
||||
// if you have null fields and use SELECT *, you must use sql.Null* in your struct
|
||||
places := []Place{}
|
||||
err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
usa, singsing, honkers := places[0], places[1], places[2]
|
||||
|
||||
fmt.Printf("%#v\n%#v\n%#v\n", usa, singsing, honkers)
|
||||
// Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
|
||||
// Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65}
|
||||
// Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852}
|
||||
|
||||
// Loop through rows using only one struct
|
||||
place := Place{}
|
||||
rows, err := db.Queryx("SELECT * FROM place")
|
||||
for rows.Next() {
|
||||
err := rows.StructScan(&place)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fmt.Printf("%#v\n", place)
|
||||
}
|
||||
// Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
|
||||
// Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852}
|
||||
// Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65}
|
||||
|
||||
// Named queries, using `:name` as the bindvar. Automatic bindvar support
|
||||
// which takes into account the dbtype based on the driverName on sqlx.Open/Connect
|
||||
_, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`,
|
||||
map[string]interface{}{
|
||||
"first": "Bin",
|
||||
"last": "Smuth",
|
||||
"email": "bensmith@allblacks.nz",
|
||||
})
|
||||
|
||||
// Selects Mr. Smith from the database
|
||||
rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:fn`, map[string]interface{}{"fn": "Bin"})
|
||||
|
||||
// Named queries can also use structs. Their bind names follow the same rules
|
||||
// as the name -> db mapping, so struct fields are lowercased and the `db` tag
|
||||
// is taken into consideration.
|
||||
rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason)
|
||||
}
|
||||
```
|
||||
|
207
vendor/github.com/jmoiron/sqlx/bind.go
generated
vendored
Normal file
207
vendor/github.com/jmoiron/sqlx/bind.go
generated
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
package sqlx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jmoiron/sqlx/reflectx"
|
||||
)
|
||||
|
||||
// Bindvar types supported by Rebind, BindMap and BindStruct.
|
||||
const (
|
||||
UNKNOWN = iota
|
||||
QUESTION
|
||||
DOLLAR
|
||||
NAMED
|
||||
)
|
||||
|
||||
// BindType returns the bindtype for a given database given a drivername.
|
||||
func BindType(driverName string) int {
|
||||
switch driverName {
|
||||
case "postgres", "pgx":
|
||||
return DOLLAR
|
||||
case "mysql":
|
||||
return QUESTION
|
||||
case "sqlite3":
|
||||
return QUESTION
|
||||
case "oci8", "ora", "goracle":
|
||||
return NAMED
|
||||
}
|
||||
return UNKNOWN
|
||||
}
|
||||
|
||||
// FIXME: this should be able to be tolerant of escaped ?'s in queries without
|
||||
// losing much speed, and should be to avoid confusion.
|
||||
|
||||
// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
|
||||
func Rebind(bindType int, query string) string {
|
||||
switch bindType {
|
||||
case QUESTION, UNKNOWN:
|
||||
return query
|
||||
}
|
||||
|
||||
// Add space enough for 10 params before we have to allocate
|
||||
rqb := make([]byte, 0, len(query)+10)
|
||||
|
||||
var i, j int
|
||||
|
||||
for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") {
|
||||
rqb = append(rqb, query[:i]...)
|
||||
|
||||
switch bindType {
|
||||
case DOLLAR:
|
||||
rqb = append(rqb, '$')
|
||||
case NAMED:
|
||||
rqb = append(rqb, ':', 'a', 'r', 'g')
|
||||
}
|
||||
|
||||
j++
|
||||
rqb = strconv.AppendInt(rqb, int64(j), 10)
|
||||
|
||||
query = query[i+1:]
|
||||
}
|
||||
|
||||
return string(append(rqb, query...))
|
||||
}
|
||||
|
||||
// Experimental implementation of Rebind which uses a bytes.Buffer. The code is
|
||||
// much simpler and should be more resistant to odd unicode, but it is twice as
|
||||
// slow. Kept here for benchmarking purposes and to possibly replace Rebind if
|
||||
// problems arise with its somewhat naive handling of unicode.
|
||||
func rebindBuff(bindType int, query string) string {
|
||||
if bindType != DOLLAR {
|
||||
return query
|
||||
}
|
||||
|
||||
b := make([]byte, 0, len(query))
|
||||
rqb := bytes.NewBuffer(b)
|
||||
j := 1
|
||||
for _, r := range query {
|
||||
if r == '?' {
|
||||
rqb.WriteRune('$')
|
||||
rqb.WriteString(strconv.Itoa(j))
|
||||
j++
|
||||
} else {
|
||||
rqb.WriteRune(r)
|
||||
}
|
||||
}
|
||||
|
||||
return rqb.String()
|
||||
}
|
||||
|
||||
// In expands slice values in args, returning the modified query string
|
||||
// and a new arg list that can be executed by a database. The `query` should
|
||||
// use the `?` bindVar. The return value uses the `?` bindVar.
|
||||
func In(query string, args ...interface{}) (string, []interface{}, error) {
|
||||
// argMeta stores reflect.Value and length for slices and
|
||||
// the value itself for non-slice arguments
|
||||
type argMeta struct {
|
||||
v reflect.Value
|
||||
i interface{}
|
||||
length int
|
||||
}
|
||||
|
||||
var flatArgsCount int
|
||||
var anySlices bool
|
||||
|
||||
meta := make([]argMeta, len(args))
|
||||
|
||||
for i, arg := range args {
|
||||
v := reflect.ValueOf(arg)
|
||||
t := reflectx.Deref(v.Type())
|
||||
|
||||
if t.Kind() == reflect.Slice {
|
||||
meta[i].length = v.Len()
|
||||
meta[i].v = v
|
||||
|
||||
anySlices = true
|
||||
flatArgsCount += meta[i].length
|
||||
|
||||
if meta[i].length == 0 {
|
||||
return "", nil, errors.New("empty slice passed to 'in' query")
|
||||
}
|
||||
} else {
|
||||
meta[i].i = arg
|
||||
flatArgsCount++
|
||||
}
|
||||
}
|
||||
|
||||
// don't do any parsing if there aren't any slices; note that this means
|
||||
// some errors that we might have caught below will not be returned.
|
||||
if !anySlices {
|
||||
return query, args, nil
|
||||
}
|
||||
|
||||
newArgs := make([]interface{}, 0, flatArgsCount)
|
||||
buf := bytes.NewBuffer(make([]byte, 0, len(query)+len(", ?")*flatArgsCount))
|
||||
|
||||
var arg, offset int
|
||||
|
||||
for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {
|
||||
if arg >= len(meta) {
|
||||
// if an argument wasn't passed, lets return an error; this is
|
||||
// not actually how database/sql Exec/Query works, but since we are
|
||||
// creating an argument list programmatically, we want to be able
|
||||
// to catch these programmer errors earlier.
|
||||
return "", nil, errors.New("number of bindVars exceeds arguments")
|
||||
}
|
||||
|
||||
argMeta := meta[arg]
|
||||
arg++
|
||||
|
||||
// not a slice, continue.
|
||||
// our questionmark will either be written before the next expansion
|
||||
// of a slice or after the loop when writing the rest of the query
|
||||
if argMeta.length == 0 {
|
||||
offset = offset + i + 1
|
||||
newArgs = append(newArgs, argMeta.i)
|
||||
continue
|
||||
}
|
||||
|
||||
// write everything up to and including our ? character
|
||||
buf.WriteString(query[:offset+i+1])
|
||||
|
||||
for si := 1; si < argMeta.length; si++ {
|
||||
buf.WriteString(", ?")
|
||||
}
|
||||
|
||||
newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)
|
||||
|
||||
// slice the query and reset the offset. this avoids some bookkeeping for
|
||||
// the write after the loop
|
||||
query = query[offset+i+1:]
|
||||
offset = 0
|
||||
}
|
||||
|
||||
buf.WriteString(query)
|
||||
|
||||
if arg < len(meta) {
|
||||
return "", nil, errors.New("number of bindVars less than number arguments")
|
||||
}
|
||||
|
||||
return buf.String(), newArgs, nil
|
||||
}
|
||||
|
||||
func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
|
||||
switch val := v.Interface().(type) {
|
||||
case []interface{}:
|
||||
args = append(args, val...)
|
||||
case []int:
|
||||
for i := range val {
|
||||
args = append(args, val[i])
|
||||
}
|
||||
case []string:
|
||||
for i := range val {
|
||||
args = append(args, val[i])
|
||||
}
|
||||
default:
|
||||
for si := 0; si < vlen; si++ {
|
||||
args = append(args, v.Index(si).Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
12
vendor/github.com/jmoiron/sqlx/doc.go
generated
vendored
Normal file
12
vendor/github.com/jmoiron/sqlx/doc.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Package sqlx provides general purpose extensions to database/sql.
|
||||
//
|
||||
// It is intended to seamlessly wrap database/sql and provide convenience
|
||||
// methods which are useful in the development of database driven applications.
|
||||
// None of the underlying database/sql methods are changed. Instead all extended
|
||||
// behavior is implemented through new methods defined on wrapper types.
|
||||
//
|
||||
// Additions include scanning into structs, named query support, rebinding
|
||||
// queries for different drivers, convenient shorthands for common error handling
|
||||
// and more.
|
||||
//
|
||||
package sqlx
|
344
vendor/github.com/jmoiron/sqlx/named.go
generated
vendored
Normal file
344
vendor/github.com/jmoiron/sqlx/named.go
generated
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
package sqlx
|
||||
|
||||
// Named Query Support
|
||||
//
|
||||
// * BindMap - bind query bindvars to map/struct args
|
||||
// * NamedExec, NamedQuery - named query w/ struct or map
|
||||
// * NamedStmt - a pre-compiled named query which is a prepared statement
|
||||
//
|
||||
// Internal Interfaces:
|
||||
//
|
||||
// * compileNamedQuery - rebind a named query, returning a query and list of names
|
||||
// * bindArgs, bindMapArgs, bindAnyArgs - given a list of names, return an arglist
|
||||
//
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unicode"
|
||||
|
||||
"github.com/jmoiron/sqlx/reflectx"
|
||||
)
|
||||
|
||||
// NamedStmt is a prepared statement that executes named queries. Prepare it
|
||||
// how you would execute a NamedQuery, but pass in a struct or map when executing.
|
||||
type NamedStmt struct {
|
||||
Params []string
|
||||
QueryString string
|
||||
Stmt *Stmt
|
||||
}
|
||||
|
||||
// Close closes the named statement.
|
||||
func (n *NamedStmt) Close() error {
|
||||
return n.Stmt.Close()
|
||||
}
|
||||
|
||||
// Exec executes a named statement using the struct passed.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) Exec(arg interface{}) (sql.Result, error) {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return *new(sql.Result), err
|
||||
}
|
||||
return n.Stmt.Exec(args...)
|
||||
}
|
||||
|
||||
// Query executes a named statement using the struct argument, returning rows.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) Query(arg interface{}) (*sql.Rows, error) {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return n.Stmt.Query(args...)
|
||||
}
|
||||
|
||||
// QueryRow executes a named statement against the database. Because sqlx cannot
|
||||
// create a *sql.Row with an error condition pre-set for binding errors, sqlx
|
||||
// returns a *sqlx.Row instead.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryRow(arg interface{}) *Row {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return &Row{err: err}
|
||||
}
|
||||
return n.Stmt.QueryRowx(args...)
|
||||
}
|
||||
|
||||
// MustExec execs a NamedStmt, panicing on error
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) MustExec(arg interface{}) sql.Result {
|
||||
res, err := n.Exec(arg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Queryx using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) Queryx(arg interface{}) (*Rows, error) {
|
||||
r, err := n.Query(arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err
|
||||
}
|
||||
|
||||
// QueryRowx this NamedStmt. Because of limitations with QueryRow, this is
|
||||
// an alias for QueryRow.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryRowx(arg interface{}) *Row {
|
||||
return n.QueryRow(arg)
|
||||
}
|
||||
|
||||
// Select using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) Select(dest interface{}, arg interface{}) error {
|
||||
rows, err := n.Queryx(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if something happens here, we want to make sure the rows are Closed
|
||||
defer rows.Close()
|
||||
return scanAll(rows, dest, false)
|
||||
}
|
||||
|
||||
// Get using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) Get(dest interface{}, arg interface{}) error {
|
||||
r := n.QueryRowx(arg)
|
||||
return r.scanAny(dest, false)
|
||||
}
|
||||
|
||||
// Unsafe creates an unsafe version of the NamedStmt
|
||||
func (n *NamedStmt) Unsafe() *NamedStmt {
|
||||
r := &NamedStmt{Params: n.Params, Stmt: n.Stmt, QueryString: n.QueryString}
|
||||
r.Stmt.unsafe = true
|
||||
return r
|
||||
}
|
||||
|
||||
// A union interface of preparer and binder, required to be able to prepare
|
||||
// named statements (as the bindtype must be determined).
|
||||
type namedPreparer interface {
|
||||
Preparer
|
||||
binder
|
||||
}
|
||||
|
||||
func prepareNamed(p namedPreparer, query string) (*NamedStmt, error) {
|
||||
bindType := BindType(p.DriverName())
|
||||
q, args, err := compileNamedQuery([]byte(query), bindType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stmt, err := Preparex(p, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &NamedStmt{
|
||||
QueryString: q,
|
||||
Params: args,
|
||||
Stmt: stmt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func bindAnyArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {
|
||||
if maparg, ok := arg.(map[string]interface{}); ok {
|
||||
return bindMapArgs(names, maparg)
|
||||
}
|
||||
return bindArgs(names, arg, m)
|
||||
}
|
||||
|
||||
// private interface to generate a list of interfaces from a given struct
|
||||
// type, given a list of names to pull out of the struct. Used by public
|
||||
// BindStruct interface.
|
||||
func bindArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {
|
||||
arglist := make([]interface{}, 0, len(names))
|
||||
|
||||
// grab the indirected value of arg
|
||||
v := reflect.ValueOf(arg)
|
||||
for v = reflect.ValueOf(arg); v.Kind() == reflect.Ptr; {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
fields := m.TraversalsByName(v.Type(), names)
|
||||
for i, t := range fields {
|
||||
if len(t) == 0 {
|
||||
return arglist, fmt.Errorf("could not find name %s in %#v", names[i], arg)
|
||||
}
|
||||
val := reflectx.FieldByIndexesReadOnly(v, t)
|
||||
arglist = append(arglist, val.Interface())
|
||||
}
|
||||
|
||||
return arglist, nil
|
||||
}
|
||||
|
||||
// like bindArgs, but for maps.
|
||||
func bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, error) {
|
||||
arglist := make([]interface{}, 0, len(names))
|
||||
|
||||
for _, name := range names {
|
||||
val, ok := arg[name]
|
||||
if !ok {
|
||||
return arglist, fmt.Errorf("could not find name %s in %#v", name, arg)
|
||||
}
|
||||
arglist = append(arglist, val)
|
||||
}
|
||||
return arglist, nil
|
||||
}
|
||||
|
||||
// bindStruct binds a named parameter query with fields from a struct argument.
|
||||
// The rules for binding field names to parameter names follow the same
|
||||
// conventions as for StructScan, including obeying the `db` struct tags.
|
||||
func bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {
|
||||
bound, names, err := compileNamedQuery([]byte(query), bindType)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
|
||||
arglist, err := bindArgs(names, arg, m)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
|
||||
return bound, arglist, nil
|
||||
}
|
||||
|
||||
// bindMap binds a named parameter query with a map of arguments.
|
||||
func bindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) {
|
||||
bound, names, err := compileNamedQuery([]byte(query), bindType)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
|
||||
arglist, err := bindMapArgs(names, args)
|
||||
return bound, arglist, err
|
||||
}
|
||||
|
||||
// -- Compilation of Named Queries
|
||||
|
||||
// Allow digits and letters in bind params; additionally runes are
|
||||
// checked against underscores, meaning that bind params can have be
|
||||
// alphanumeric with underscores. Mind the difference between unicode
|
||||
// digits and numbers, where '5' is a digit but '五' is not.
|
||||
var allowedBindRunes = []*unicode.RangeTable{unicode.Letter, unicode.Digit}
|
||||
|
||||
// FIXME: this function isn't safe for unicode named params, as a failing test
|
||||
// can testify. This is not a regression but a failure of the original code
|
||||
// as well. It should be modified to range over runes in a string rather than
|
||||
// bytes, even though this is less convenient and slower. Hopefully the
|
||||
// addition of the prepared NamedStmt (which will only do this once) will make
|
||||
// up for the slightly slower ad-hoc NamedExec/NamedQuery.
|
||||
|
||||
// compile a NamedQuery into an unbound query (using the '?' bindvar) and
|
||||
// a list of names.
|
||||
func compileNamedQuery(qs []byte, bindType int) (query string, names []string, err error) {
|
||||
names = make([]string, 0, 10)
|
||||
rebound := make([]byte, 0, len(qs))
|
||||
|
||||
inName := false
|
||||
last := len(qs) - 1
|
||||
currentVar := 1
|
||||
name := make([]byte, 0, 10)
|
||||
|
||||
for i, b := range qs {
|
||||
// a ':' while we're in a name is an error
|
||||
if b == ':' {
|
||||
// if this is the second ':' in a '::' escape sequence, append a ':'
|
||||
if inName && i > 0 && qs[i-1] == ':' {
|
||||
rebound = append(rebound, ':')
|
||||
inName = false
|
||||
continue
|
||||
} else if inName {
|
||||
err = errors.New("unexpected `:` while reading named param at " + strconv.Itoa(i))
|
||||
return query, names, err
|
||||
}
|
||||
inName = true
|
||||
name = []byte{}
|
||||
// if we're in a name, and this is an allowed character, continue
|
||||
} else if inName && (unicode.IsOneOf(allowedBindRunes, rune(b)) || b == '_' || b == '.') && i != last {
|
||||
// append the byte to the name if we are in a name and not on the last byte
|
||||
name = append(name, b)
|
||||
// if we're in a name and it's not an allowed character, the name is done
|
||||
} else if inName {
|
||||
inName = false
|
||||
// if this is the final byte of the string and it is part of the name, then
|
||||
// make sure to add it to the name
|
||||
if i == last && unicode.IsOneOf(allowedBindRunes, rune(b)) {
|
||||
name = append(name, b)
|
||||
}
|
||||
// add the string representation to the names list
|
||||
names = append(names, string(name))
|
||||
// add a proper bindvar for the bindType
|
||||
switch bindType {
|
||||
// oracle only supports named type bind vars even for positional
|
||||
case NAMED:
|
||||
rebound = append(rebound, ':')
|
||||
rebound = append(rebound, name...)
|
||||
case QUESTION, UNKNOWN:
|
||||
rebound = append(rebound, '?')
|
||||
case DOLLAR:
|
||||
rebound = append(rebound, '$')
|
||||
for _, b := range strconv.Itoa(currentVar) {
|
||||
rebound = append(rebound, byte(b))
|
||||
}
|
||||
currentVar++
|
||||
}
|
||||
// add this byte to string unless it was not part of the name
|
||||
if i != last {
|
||||
rebound = append(rebound, b)
|
||||
} else if !unicode.IsOneOf(allowedBindRunes, rune(b)) {
|
||||
rebound = append(rebound, b)
|
||||
}
|
||||
} else {
|
||||
// this is a normal byte and should just go onto the rebound query
|
||||
rebound = append(rebound, b)
|
||||
}
|
||||
}
|
||||
|
||||
return string(rebound), names, err
|
||||
}
|
||||
|
||||
// BindNamed binds a struct or a map to a query with named parameters.
|
||||
// DEPRECATED: use sqlx.Named` instead of this, it may be removed in future.
|
||||
func BindNamed(bindType int, query string, arg interface{}) (string, []interface{}, error) {
|
||||
return bindNamedMapper(bindType, query, arg, mapper())
|
||||
}
|
||||
|
||||
// Named takes a query using named parameters and an argument and
|
||||
// returns a new query with a list of args that can be executed by
|
||||
// a database. The return value uses the `?` bindvar.
|
||||
func Named(query string, arg interface{}) (string, []interface{}, error) {
|
||||
return bindNamedMapper(QUESTION, query, arg, mapper())
|
||||
}
|
||||
|
||||
func bindNamedMapper(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {
|
||||
if maparg, ok := arg.(map[string]interface{}); ok {
|
||||
return bindMap(bindType, query, maparg)
|
||||
}
|
||||
return bindStruct(bindType, query, arg, m)
|
||||
}
|
||||
|
||||
// NamedQuery binds a named query and then runs Query on the result using the
|
||||
// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with
|
||||
// map[string]interface{} types.
|
||||
func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.Queryx(q, args...)
|
||||
}
|
||||
|
||||
// NamedExec uses BindStruct to get a query executable by the driver and
|
||||
// then runs Exec on the result. Returns an error from the binding
|
||||
// or the query excution itself.
|
||||
func NamedExec(e Ext, query string, arg interface{}) (sql.Result, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.Exec(q, args...)
|
||||
}
|
132
vendor/github.com/jmoiron/sqlx/named_context.go
generated
vendored
Normal file
132
vendor/github.com/jmoiron/sqlx/named_context.go
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// +build go1.8
|
||||
|
||||
package sqlx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// A union interface of contextPreparer and binder, required to be able to
|
||||
// prepare named statements with context (as the bindtype must be determined).
|
||||
type namedPreparerContext interface {
|
||||
PreparerContext
|
||||
binder
|
||||
}
|
||||
|
||||
func prepareNamedContext(ctx context.Context, p namedPreparerContext, query string) (*NamedStmt, error) {
|
||||
bindType := BindType(p.DriverName())
|
||||
q, args, err := compileNamedQuery([]byte(query), bindType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stmt, err := PreparexContext(ctx, p, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &NamedStmt{
|
||||
QueryString: q,
|
||||
Params: args,
|
||||
Stmt: stmt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExecContext executes a named statement using the struct passed.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) ExecContext(ctx context.Context, arg interface{}) (sql.Result, error) {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return *new(sql.Result), err
|
||||
}
|
||||
return n.Stmt.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryContext executes a named statement using the struct argument, returning rows.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryContext(ctx context.Context, arg interface{}) (*sql.Rows, error) {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return n.Stmt.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryRowContext executes a named statement against the database. Because sqlx cannot
|
||||
// create a *sql.Row with an error condition pre-set for binding errors, sqlx
|
||||
// returns a *sqlx.Row instead.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryRowContext(ctx context.Context, arg interface{}) *Row {
|
||||
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
|
||||
if err != nil {
|
||||
return &Row{err: err}
|
||||
}
|
||||
return n.Stmt.QueryRowxContext(ctx, args...)
|
||||
}
|
||||
|
||||
// MustExecContext execs a NamedStmt, panicing on error
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) MustExecContext(ctx context.Context, arg interface{}) sql.Result {
|
||||
res, err := n.ExecContext(ctx, arg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// QueryxContext using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryxContext(ctx context.Context, arg interface{}) (*Rows, error) {
|
||||
r, err := n.QueryContext(ctx, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err
|
||||
}
|
||||
|
||||
// QueryRowxContext this NamedStmt. Because of limitations with QueryRow, this is
|
||||
// an alias for QueryRow.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) QueryRowxContext(ctx context.Context, arg interface{}) *Row {
|
||||
return n.QueryRowContext(ctx, arg)
|
||||
}
|
||||
|
||||
// SelectContext using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) SelectContext(ctx context.Context, dest interface{}, arg interface{}) error {
|
||||
rows, err := n.QueryxContext(ctx, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if something happens here, we want to make sure the rows are Closed
|
||||
defer rows.Close()
|
||||
return scanAll(rows, dest, false)
|
||||
}
|
||||
|
||||
// GetContext using this NamedStmt
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (n *NamedStmt) GetContext(ctx context.Context, dest interface{}, arg interface{}) error {
|
||||
r := n.QueryRowxContext(ctx, arg)
|
||||
return r.scanAny(dest, false)
|
||||
}
|
||||
|
||||
// NamedQueryContext binds a named query and then runs Query on the result using the
|
||||
// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with
|
||||
// map[string]interface{} types.
|
||||
func NamedQueryContext(ctx context.Context, e ExtContext, query string, arg interface{}) (*Rows, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.QueryxContext(ctx, q, args...)
|
||||
}
|
||||
|
||||
// NamedExecContext uses BindStruct to get a query executable by the driver and
|
||||
// then runs Exec on the result. Returns an error from the binding
|
||||
// or the query excution itself.
|
||||
func NamedExecContext(ctx context.Context, e ExtContext, query string, arg interface{}) (sql.Result, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.ExecContext(ctx, q, args...)
|
||||
}
|
136
vendor/github.com/jmoiron/sqlx/named_context_test.go
generated
vendored
Normal file
136
vendor/github.com/jmoiron/sqlx/named_context_test.go
generated
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
// +build go1.8
|
||||
|
||||
package sqlx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNamedContextQueries(t *testing.T) {
|
||||
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T) {
|
||||
loadDefaultFixture(db, t)
|
||||
test := Test{t}
|
||||
var ns *NamedStmt
|
||||
var err error
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Check that invalid preparations fail
|
||||
ns, err = db.PrepareNamedContext(ctx, "SELECT * FROM person WHERE first_name=:first:name")
|
||||
if err == nil {
|
||||
t.Error("Expected an error with invalid prepared statement.")
|
||||
}
|
||||
|
||||
ns, err = db.PrepareNamedContext(ctx, "invalid sql")
|
||||
if err == nil {
|
||||
t.Error("Expected an error with invalid prepared statement.")
|
||||
}
|
||||
|
||||
// Check closing works as anticipated
|
||||
ns, err = db.PrepareNamedContext(ctx, "SELECT * FROM person WHERE first_name=:first_name")
|
||||
test.Error(err)
|
||||
err = ns.Close()
|
||||
test.Error(err)
|
||||
|
||||
ns, err = db.PrepareNamedContext(ctx, `
|
||||
SELECT first_name, last_name, email
|
||||
FROM person WHERE first_name=:first_name AND email=:email`)
|
||||
test.Error(err)
|
||||
|
||||
// test Queryx w/ uses Query
|
||||
p := Person{FirstName: "Jason", LastName: "Moiron", Email: "jmoiron@jmoiron.net"}
|
||||
|
||||
rows, err := ns.QueryxContext(ctx, p)
|
||||
test.Error(err)
|
||||
for rows.Next() {
|
||||
var p2 Person
|
||||
rows.StructScan(&p2)
|
||||
if p.FirstName != p2.FirstName {
|
||||
t.Errorf("got %s, expected %s", p.FirstName, p2.FirstName)
|
||||
}
|
||||
if p.LastName != p2.LastName {
|
||||
t.Errorf("got %s, expected %s", p.LastName, p2.LastName)
|
||||
}
|
||||
if p.Email != p2.Email {
|
||||
t.Errorf("got %s, expected %s", p.Email, p2.Email)
|
||||
}
|
||||
}
|
||||
|
||||
// test Select
|
||||
people := make([]Person, 0, 5)
|
||||
err = ns.SelectContext(ctx, &people, p)
|
||||
test.Error(err)
|
||||
|
||||
if len(people) != 1 {
|
||||
t.Errorf("got %d results, expected %d", len(people), 1)
|
||||
}
|
||||
if p.FirstName != people[0].FirstName {
|
||||
t.Errorf("got %s, expected %s", p.FirstName, people[0].FirstName)
|
||||
}
|
||||
if p.LastName != people[0].LastName {
|
||||
t.Errorf("got %s, expected %s", p.LastName, people[0].LastName)
|
||||
}
|
||||
if p.Email != people[0].Email {
|
||||
t.Errorf("got %s, expected %s", p.Email, people[0].Email)
|
||||
}
|
||||
|
||||
// test Exec
|
||||
ns, err = db.PrepareNamedContext(ctx, `
|
||||
INSERT INTO person (first_name, last_name, email)
|
||||
VALUES (:first_name, :last_name, :email)`)
|
||||
test.Error(err)
|
||||
|
||||
js := Person{
|
||||
FirstName: "Julien",
|
||||
LastName: "Savea",
|
||||
Email: "jsavea@ab.co.nz",
|
||||
}
|
||||
_, err = ns.ExecContext(ctx, js)
|
||||
test.Error(err)
|
||||
|
||||
// Make sure we can pull him out again
|
||||
p2 := Person{}
|
||||
db.GetContext(ctx, &p2, db.Rebind("SELECT * FROM person WHERE email=?"), js.Email)
|
||||
if p2.Email != js.Email {
|
||||
t.Errorf("expected %s, got %s", js.Email, p2.Email)
|
||||
}
|
||||
|
||||
// test Txn NamedStmts
|
||||
tx := db.MustBeginTx(ctx, nil)
|
||||
txns := tx.NamedStmtContext(ctx, ns)
|
||||
|
||||
// We're going to add Steven in this txn
|
||||
sl := Person{
|
||||
FirstName: "Steven",
|
||||
LastName: "Luatua",
|
||||
Email: "sluatua@ab.co.nz",
|
||||
}
|
||||
|
||||
_, err = txns.ExecContext(ctx, sl)
|
||||
test.Error(err)
|
||||
// then rollback...
|
||||
tx.Rollback()
|
||||
// looking for Steven after a rollback should fail
|
||||
err = db.GetContext(ctx, &p2, db.Rebind("SELECT * FROM person WHERE email=?"), sl.Email)
|
||||
if err != sql.ErrNoRows {
|
||||
t.Errorf("expected no rows error, got %v", err)
|
||||
}
|
||||
|
||||
// now do the same, but commit
|
||||
tx = db.MustBeginTx(ctx, nil)
|
||||
txns = tx.NamedStmtContext(ctx, ns)
|
||||
_, err = txns.ExecContext(ctx, sl)
|
||||
test.Error(err)
|
||||
tx.Commit()
|
||||
|
||||
// looking for Steven after a Commit should succeed
|
||||
err = db.GetContext(ctx, &p2, db.Rebind("SELECT * FROM person WHERE email=?"), sl.Email)
|
||||
test.Error(err)
|
||||
if p2.Email != sl.Email {
|
||||
t.Errorf("expected %s, got %s", sl.Email, p2.Email)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
227
vendor/github.com/jmoiron/sqlx/named_test.go
generated
vendored
Normal file
227
vendor/github.com/jmoiron/sqlx/named_test.go
generated
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
package sqlx
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompileQuery(t *testing.T) {
|
||||
table := []struct {
|
||||
Q, R, D, N string
|
||||
V []string
|
||||
}{
|
||||
// basic test for named parameters, invalid char ',' terminating
|
||||
{
|
||||
Q: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,
|
||||
R: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,
|
||||
D: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`,
|
||||
N: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,
|
||||
V: []string{"name", "age", "first", "last"},
|
||||
},
|
||||
// This query tests a named parameter ending the string as well as numbers
|
||||
{
|
||||
Q: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,
|
||||
R: `SELECT * FROM a WHERE first_name=? AND last_name=?`,
|
||||
D: `SELECT * FROM a WHERE first_name=$1 AND last_name=$2`,
|
||||
N: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,
|
||||
V: []string{"name1", "name2"},
|
||||
},
|
||||
{
|
||||
Q: `SELECT "::foo" FROM a WHERE first_name=:name1 AND last_name=:name2`,
|
||||
R: `SELECT ":foo" FROM a WHERE first_name=? AND last_name=?`,
|
||||
D: `SELECT ":foo" FROM a WHERE first_name=$1 AND last_name=$2`,
|
||||
N: `SELECT ":foo" FROM a WHERE first_name=:name1 AND last_name=:name2`,
|
||||
V: []string{"name1", "name2"},
|
||||
},
|
||||
{
|
||||
Q: `SELECT 'a::b::c' || first_name, '::::ABC::_::' FROM person WHERE first_name=:first_name AND last_name=:last_name`,
|
||||
R: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=? AND last_name=?`,
|
||||
D: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=$1 AND last_name=$2`,
|
||||
N: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=:first_name AND last_name=:last_name`,
|
||||
V: []string{"first_name", "last_name"},
|
||||
},
|
||||
/* This unicode awareness test sadly fails, because of our byte-wise worldview.
|
||||
* We could certainly iterate by Rune instead, though it's a great deal slower,
|
||||
* it's probably the RightWay(tm)
|
||||
{
|
||||
Q: `INSERT INTO foo (a,b,c,d) VALUES (:あ, :b, :キコ, :名前)`,
|
||||
R: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,
|
||||
D: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`,
|
||||
N: []string{"name", "age", "first", "last"},
|
||||
},
|
||||
*/
|
||||
}
|
||||
|
||||
for _, test := range table {
|
||||
qr, names, err := compileNamedQuery([]byte(test.Q), QUESTION)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if qr != test.R {
|
||||
t.Errorf("expected %s, got %s", test.R, qr)
|
||||
}
|
||||
if len(names) != len(test.V) {
|
||||
t.Errorf("expected %#v, got %#v", test.V, names)
|
||||
} else {
|
||||
for i, name := range names {
|
||||
if name != test.V[i] {
|
||||
t.Errorf("expected %dth name to be %s, got %s", i+1, test.V[i], name)
|
||||
}
|
||||
}
|
||||
}
|
||||
qd, _, _ := compileNamedQuery([]byte(test.Q), DOLLAR)
|
||||
if qd != test.D {
|
||||
t.Errorf("\nexpected: `%s`\ngot: `%s`", test.D, qd)
|
||||
}
|
||||
|
||||
qq, _, _ := compileNamedQuery([]byte(test.Q), NAMED)
|
||||
if qq != test.N {
|
||||
t.Errorf("\nexpected: `%s`\ngot: `%s`\n(len: %d vs %d)", test.N, qq, len(test.N), len(qq))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (t Test) Error(err error, msg ...interface{}) {
|
||||
if err != nil {
|
||||
if len(msg) == 0 {
|
||||
t.t.Error(err)
|
||||
} else {
|
||||
t.t.Error(msg...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t Test) Errorf(err error, format string, args ...interface{}) {
|
||||
if err != nil {
|
||||
t.t.Errorf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedQueries(t *testing.T) {
|
||||
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T) {
|
||||
loadDefaultFixture(db, t)
|
||||
test := Test{t}
|
||||
var ns *NamedStmt
|
||||
var err error
|
||||
|
||||
// Check that invalid preparations fail
|
||||
ns, err = db.PrepareNamed("SELECT * FROM person WHERE first_name=:first:name")
|
||||
if err == nil {
|
||||
t.Error("Expected an error with invalid prepared statement.")
|
||||
}
|
||||
|
||||
ns, err = db.PrepareNamed("invalid sql")
|
||||
if err == nil {
|
||||
t.Error("Expected an error with invalid prepared statement.")
|
||||
}
|
||||
|
||||
// Check closing works as anticipated
|
||||
ns, err = db.PrepareNamed("SELECT * FROM person WHERE first_name=:first_name")
|
||||
test.Error(err)
|
||||
err = ns.Close()
|
||||
test.Error(err)
|
||||
|
||||
ns, err = db.PrepareNamed(`
|
||||
SELECT first_name, last_name, email
|
||||
FROM person WHERE first_name=:first_name AND email=:email`)
|
||||
test.Error(err)
|
||||
|
||||
// test Queryx w/ uses Query
|
||||
p := Person{FirstName: "Jason", LastName: "Moiron", Email: "jmoiron@jmoiron.net"}
|
||||
|
||||
rows, err := ns.Queryx(p)
|
||||
test.Error(err)
|
||||
for rows.Next() {
|
||||
var p2 Person
|
||||
rows.StructScan(&p2)
|
||||
if p.FirstName != p2.FirstName {
|
||||
t.Errorf("got %s, expected %s", p.FirstName, p2.FirstName)
|
||||
}
|
||||
if p.LastName != p2.LastName {
|
||||
t.Errorf("got %s, expected %s", p.LastName, p2.LastName)
|
||||
}
|
||||
if p.Email != p2.Email {
|
||||
t.Errorf("got %s, expected %s", p.Email, p2.Email)
|
||||
}
|
||||
}
|
||||
|
||||
// test Select
|
||||
people := make([]Person, 0, 5)
|
||||
err = ns.Select(&people, p)
|
||||
test.Error(err)
|
||||
|
||||
if len(people) != 1 {
|
||||
t.Errorf("got %d results, expected %d", len(people), 1)
|
||||
}
|
||||
if p.FirstName != people[0].FirstName {
|
||||
t.Errorf("got %s, expected %s", p.FirstName, people[0].FirstName)
|
||||
}
|
||||
if p.LastName != people[0].LastName {
|
||||
t.Errorf("got %s, expected %s", p.LastName, people[0].LastName)
|
||||
}
|
||||
if p.Email != people[0].Email {
|
||||
t.Errorf("got %s, expected %s", p.Email, people[0].Email)
|
||||
}
|
||||
|
||||
// test Exec
|
||||
ns, err = db.PrepareNamed(`
|
||||
INSERT INTO person (first_name, last_name, email)
|
||||
VALUES (:first_name, :last_name, :email)`)
|
||||
test.Error(err)
|
||||
|
||||
js := Person{
|
||||
FirstName: "Julien",
|
||||
LastName: "Savea",
|
||||
Email: "jsavea@ab.co.nz",
|
||||
}
|
||||
_, err = ns.Exec(js)
|
||||
test.Error(err)
|
||||
|
||||
// Make sure we can pull him out again
|
||||
p2 := Person{}
|
||||
db.Get(&p2, db.Rebind("SELECT * FROM person WHERE email=?"), js.Email)
|
||||
if p2.Email != js.Email {
|
||||
t.Errorf("expected %s, got %s", js.Email, p2.Email)
|
||||
}
|
||||
|
||||
// test Txn NamedStmts
|
||||
tx := db.MustBegin()
|
||||
txns := tx.NamedStmt(ns)
|
||||
|
||||
// We're going to add Steven in this txn
|
||||
sl := Person{
|
||||
FirstName: "Steven",
|
||||
LastName: "Luatua",
|
||||
Email: "sluatua@ab.co.nz",
|
||||
}
|
||||
|
||||
_, err = txns.Exec(sl)
|
||||
test.Error(err)
|
||||
// then rollback...
|
||||
tx.Rollback()
|
||||
// looking for Steven after a rollback should fail
|
||||
err = db.Get(&p2, db.Rebind("SELECT * FROM person WHERE email=?"), sl.Email)
|
||||
if err != sql.ErrNoRows {
|
||||
t.Errorf("expected no rows error, got %v", err)
|
||||
}
|
||||
|
||||
// now do the same, but commit
|
||||
tx = db.MustBegin()
|
||||
txns = tx.NamedStmt(ns)
|
||||
_, err = txns.Exec(sl)
|
||||
test.Error(err)
|
||||
tx.Commit()
|
||||
|
||||
// looking for Steven after a Commit should succeed
|
||||
err = db.Get(&p2, db.Rebind("SELECT * FROM person WHERE email=?"), sl.Email)
|
||||
test.Error(err)
|
||||
if p2.Email != sl.Email {
|
||||
t.Errorf("expected %s, got %s", sl.Email, p2.Email)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
17
vendor/github.com/jmoiron/sqlx/reflectx/README.md
generated
vendored
Normal file
17
vendor/github.com/jmoiron/sqlx/reflectx/README.md
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# reflectx
|
||||
|
||||
The sqlx package has special reflect needs. In particular, it needs to:
|
||||
|
||||
* be able to map a name to a field
|
||||
* understand embedded structs
|
||||
* understand mapping names to fields by a particular tag
|
||||
* user specified name -> field mapping functions
|
||||
|
||||
These behaviors mimic the behaviors by the standard library marshallers and also the
|
||||
behavior of standard Go accessors.
|
||||
|
||||
The first two are amply taken care of by `Reflect.Value.FieldByName`, and the third is
|
||||
addressed by `Reflect.Value.FieldByNameFunc`, but these don't quite understand struct
|
||||
tags in the ways that are vital to most marshallers, and they are slow.
|
||||
|
||||
This reflectx package extends reflect to achieve these goals.
|
422
vendor/github.com/jmoiron/sqlx/reflectx/reflect.go
generated
vendored
Normal file
422
vendor/github.com/jmoiron/sqlx/reflectx/reflect.go
generated
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
// Package reflectx implements extensions to the standard reflect lib suitable
|
||||
// for implementing marshalling and unmarshalling packages. The main Mapper type
|
||||
// allows for Go-compatible named attribute access, including accessing embedded
|
||||
// struct attributes and the ability to use functions and struct tags to
|
||||
// customize field names.
|
||||
//
|
||||
package reflectx
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A FieldInfo is metadata for a struct field.
|
||||
type FieldInfo struct {
|
||||
Index []int
|
||||
Path string
|
||||
Field reflect.StructField
|
||||
Zero reflect.Value
|
||||
Name string
|
||||
Options map[string]string
|
||||
Embedded bool
|
||||
Children []*FieldInfo
|
||||
Parent *FieldInfo
|
||||
}
|
||||
|
||||
// A StructMap is an index of field metadata for a struct.
|
||||
type StructMap struct {
|
||||
Tree *FieldInfo
|
||||
Index []*FieldInfo
|
||||
Paths map[string]*FieldInfo
|
||||
Names map[string]*FieldInfo
|
||||
}
|
||||
|
||||
// GetByPath returns a *FieldInfo for a given string path.
|
||||
func (f StructMap) GetByPath(path string) *FieldInfo {
|
||||
return f.Paths[path]
|
||||
}
|
||||
|
||||
// GetByTraversal returns a *FieldInfo for a given integer path. It is
|
||||
// analogous to reflect.FieldByIndex, but using the cached traversal
|
||||
// rather than re-executing the reflect machinery each time.
|
||||
func (f StructMap) GetByTraversal(index []int) *FieldInfo {
|
||||
if len(index) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
tree := f.Tree
|
||||
for _, i := range index {
|
||||
if i >= len(tree.Children) || tree.Children[i] == nil {
|
||||
return nil
|
||||
}
|
||||
tree = tree.Children[i]
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// Mapper is a general purpose mapper of names to struct fields. A Mapper
|
||||
// behaves like most marshallers in the standard library, obeying a field tag
|
||||
// for name mapping but also providing a basic transform function.
|
||||
type Mapper struct {
|
||||
cache map[reflect.Type]*StructMap
|
||||
tagName string
|
||||
tagMapFunc func(string) string
|
||||
mapFunc func(string) string
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// NewMapper returns a new mapper using the tagName as its struct field tag.
|
||||
// If tagName is the empty string, it is ignored.
|
||||
func NewMapper(tagName string) *Mapper {
|
||||
return &Mapper{
|
||||
cache: make(map[reflect.Type]*StructMap),
|
||||
tagName: tagName,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapperTagFunc returns a new mapper which contains a mapper for field names
|
||||
// AND a mapper for tag values. This is useful for tags like json which can
|
||||
// have values like "name,omitempty".
|
||||
func NewMapperTagFunc(tagName string, mapFunc, tagMapFunc func(string) string) *Mapper {
|
||||
return &Mapper{
|
||||
cache: make(map[reflect.Type]*StructMap),
|
||||
tagName: tagName,
|
||||
mapFunc: mapFunc,
|
||||
tagMapFunc: tagMapFunc,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapperFunc returns a new mapper which optionally obeys a field tag and
|
||||
// a struct field name mapper func given by f. Tags will take precedence, but
|
||||
// for any other field, the mapped name will be f(field.Name)
|
||||
func NewMapperFunc(tagName string, f func(string) string) *Mapper {
|
||||
return &Mapper{
|
||||
cache: make(map[reflect.Type]*StructMap),
|
||||
tagName: tagName,
|
||||
mapFunc: f,
|
||||
}
|
||||
}
|
||||
|
||||
// TypeMap returns a mapping of field strings to int slices representing
|
||||
// the traversal down the struct to reach the field.
|
||||
func (m *Mapper) TypeMap(t reflect.Type) *StructMap {
|
||||
m.mutex.Lock()
|
||||
mapping, ok := m.cache[t]
|
||||
if !ok {
|
||||
mapping = getMapping(t, m.tagName, m.mapFunc, m.tagMapFunc)
|
||||
m.cache[t] = mapping
|
||||
}
|
||||
m.mutex.Unlock()
|
||||
return mapping
|
||||
}
|
||||
|
||||
// FieldMap returns the mapper's mapping of field names to reflect values. Panics
|
||||
// if v's Kind is not Struct, or v is not Indirectable to a struct kind.
|
||||
func (m *Mapper) FieldMap(v reflect.Value) map[string]reflect.Value {
|
||||
v = reflect.Indirect(v)
|
||||
mustBe(v, reflect.Struct)
|
||||
|
||||
r := map[string]reflect.Value{}
|
||||
tm := m.TypeMap(v.Type())
|
||||
for tagName, fi := range tm.Names {
|
||||
r[tagName] = FieldByIndexes(v, fi.Index)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// FieldByName returns a field by its mapped name as a reflect.Value.
|
||||
// Panics if v's Kind is not Struct or v is not Indirectable to a struct Kind.
|
||||
// Returns zero Value if the name is not found.
|
||||
func (m *Mapper) FieldByName(v reflect.Value, name string) reflect.Value {
|
||||
v = reflect.Indirect(v)
|
||||
mustBe(v, reflect.Struct)
|
||||
|
||||
tm := m.TypeMap(v.Type())
|
||||
fi, ok := tm.Names[name]
|
||||
if !ok {
|
||||
return v
|
||||
}
|
||||
return FieldByIndexes(v, fi.Index)
|
||||
}
|
||||
|
||||
// FieldsByName returns a slice of values corresponding to the slice of names
|
||||
// for the value. Panics if v's Kind is not Struct or v is not Indirectable
|
||||
// to a struct Kind. Returns zero Value for each name not found.
|
||||
func (m *Mapper) FieldsByName(v reflect.Value, names []string) []reflect.Value {
|
||||
v = reflect.Indirect(v)
|
||||
mustBe(v, reflect.Struct)
|
||||
|
||||
tm := m.TypeMap(v.Type())
|
||||
vals := make([]reflect.Value, 0, len(names))
|
||||
for _, name := range names {
|
||||
fi, ok := tm.Names[name]
|
||||
if !ok {
|
||||
vals = append(vals, *new(reflect.Value))
|
||||
} else {
|
||||
vals = append(vals, FieldByIndexes(v, fi.Index))
|
||||
}
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// TraversalsByName returns a slice of int slices which represent the struct
|
||||
// traversals for each mapped name. Panics if t is not a struct or Indirectable
|
||||
// to a struct. Returns empty int slice for each name not found.
|
||||
func (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int {
|
||||
t = Deref(t)
|
||||
mustBe(t, reflect.Struct)
|
||||
tm := m.TypeMap(t)
|
||||
|
||||
r := make([][]int, 0, len(names))
|
||||
for _, name := range names {
|
||||
fi, ok := tm.Names[name]
|
||||
if !ok {
|
||||
r = append(r, []int{})
|
||||
} else {
|
||||
r = append(r, fi.Index)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// FieldByIndexes returns a value for the field given by the struct traversal
|
||||
// for the given value.
|
||||
func FieldByIndexes(v reflect.Value, indexes []int) reflect.Value {
|
||||
for _, i := range indexes {
|
||||
v = reflect.Indirect(v).Field(i)
|
||||
// if this is a pointer and it's nil, allocate a new value and set it
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
alloc := reflect.New(Deref(v.Type()))
|
||||
v.Set(alloc)
|
||||
}
|
||||
if v.Kind() == reflect.Map && v.IsNil() {
|
||||
v.Set(reflect.MakeMap(v.Type()))
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// FieldByIndexesReadOnly returns a value for a particular struct traversal,
|
||||
// but is not concerned with allocating nil pointers because the value is
|
||||
// going to be used for reading and not setting.
|
||||
func FieldByIndexesReadOnly(v reflect.Value, indexes []int) reflect.Value {
|
||||
for _, i := range indexes {
|
||||
v = reflect.Indirect(v).Field(i)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Deref is Indirect for reflect.Types
|
||||
func Deref(t reflect.Type) reflect.Type {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// -- helpers & utilities --
|
||||
|
||||
type kinder interface {
|
||||
Kind() reflect.Kind
|
||||
}
|
||||
|
||||
// mustBe checks a value against a kind, panicing with a reflect.ValueError
|
||||
// if the kind isn't that which is required.
|
||||
func mustBe(v kinder, expected reflect.Kind) {
|
||||
if k := v.Kind(); k != expected {
|
||||
panic(&reflect.ValueError{Method: methodName(), Kind: k})
|
||||
}
|
||||
}
|
||||
|
||||
// methodName returns the caller of the function calling methodName
|
||||
func methodName() string {
|
||||
pc, _, _, _ := runtime.Caller(2)
|
||||
f := runtime.FuncForPC(pc)
|
||||
if f == nil {
|
||||
return "unknown method"
|
||||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
type typeQueue struct {
|
||||
t reflect.Type
|
||||
fi *FieldInfo
|
||||
pp string // Parent path
|
||||
}
|
||||
|
||||
// A copying append that creates a new slice each time.
|
||||
func apnd(is []int, i int) []int {
|
||||
x := make([]int, len(is)+1)
|
||||
for p, n := range is {
|
||||
x[p] = n
|
||||
}
|
||||
x[len(x)-1] = i
|
||||
return x
|
||||
}
|
||||
|
||||
type mapf func(string) string
|
||||
|
||||
// parseName parses the tag and the target name for the given field using
|
||||
// the tagName (eg 'json' for `json:"foo"` tags), mapFunc for mapping the
|
||||
// field's name to a target name, and tagMapFunc for mapping the tag to
|
||||
// a target name.
|
||||
func parseName(field reflect.StructField, tagName string, mapFunc, tagMapFunc mapf) (tag, fieldName string) {
|
||||
// first, set the fieldName to the field's name
|
||||
fieldName = field.Name
|
||||
// if a mapFunc is set, use that to override the fieldName
|
||||
if mapFunc != nil {
|
||||
fieldName = mapFunc(fieldName)
|
||||
}
|
||||
|
||||
// if there's no tag to look for, return the field name
|
||||
if tagName == "" {
|
||||
return "", fieldName
|
||||
}
|
||||
|
||||
// if this tag is not set using the normal convention in the tag,
|
||||
// then return the fieldname.. this check is done because according
|
||||
// to the reflect documentation:
|
||||
// If the tag does not have the conventional format,
|
||||
// the value returned by Get is unspecified.
|
||||
// which doesn't sound great.
|
||||
if !strings.Contains(string(field.Tag), tagName+":") {
|
||||
return "", fieldName
|
||||
}
|
||||
|
||||
// at this point we're fairly sure that we have a tag, so lets pull it out
|
||||
tag = field.Tag.Get(tagName)
|
||||
|
||||
// if we have a mapper function, call it on the whole tag
|
||||
// XXX: this is a change from the old version, which pulled out the name
|
||||
// before the tagMapFunc could be run, but I think this is the right way
|
||||
if tagMapFunc != nil {
|
||||
tag = tagMapFunc(tag)
|
||||
}
|
||||
|
||||
// finally, split the options from the name
|
||||
parts := strings.Split(tag, ",")
|
||||
fieldName = parts[0]
|
||||
|
||||
return tag, fieldName
|
||||
}
|
||||
|
||||
// parseOptions parses options out of a tag string, skipping the name
|
||||
func parseOptions(tag string) map[string]string {
|
||||
parts := strings.Split(tag, ",")
|
||||
options := make(map[string]string, len(parts))
|
||||
if len(parts) > 1 {
|
||||
for _, opt := range parts[1:] {
|
||||
// short circuit potentially expensive split op
|
||||
if strings.Contains(opt, "=") {
|
||||
kv := strings.Split(opt, "=")
|
||||
options[kv[0]] = kv[1]
|
||||
continue
|
||||
}
|
||||
options[opt] = ""
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
// getMapping returns a mapping for the t type, using the tagName, mapFunc and
|
||||
// tagMapFunc to determine the canonical names of fields.
|
||||
func getMapping(t reflect.Type, tagName string, mapFunc, tagMapFunc mapf) *StructMap {
|
||||
m := []*FieldInfo{}
|
||||
|
||||
root := &FieldInfo{}
|
||||
queue := []typeQueue{}
|
||||
queue = append(queue, typeQueue{Deref(t), root, ""})
|
||||
|
||||
QueueLoop:
|
||||
for len(queue) != 0 {
|
||||
// pop the first item off of the queue
|
||||
tq := queue[0]
|
||||
queue = queue[1:]
|
||||
|
||||
// ignore recursive field
|
||||
for p := tq.fi.Parent; p != nil; p = p.Parent {
|
||||
if tq.fi.Field.Type == p.Field.Type {
|
||||
continue QueueLoop
|
||||
}
|
||||
}
|
||||
|
||||
nChildren := 0
|
||||
if tq.t.Kind() == reflect.Struct {
|
||||
nChildren = tq.t.NumField()
|
||||
}
|
||||
tq.fi.Children = make([]*FieldInfo, nChildren)
|
||||
|
||||
// iterate through all of its fields
|
||||
for fieldPos := 0; fieldPos < nChildren; fieldPos++ {
|
||||
|
||||
f := tq.t.Field(fieldPos)
|
||||
|
||||
// parse the tag and the target name using the mapping options for this field
|
||||
tag, name := parseName(f, tagName, mapFunc, tagMapFunc)
|
||||
|
||||
// if the name is "-", disabled via a tag, skip it
|
||||
if name == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
fi := FieldInfo{
|
||||
Field: f,
|
||||
Name: name,
|
||||
Zero: reflect.New(f.Type).Elem(),
|
||||
Options: parseOptions(tag),
|
||||
}
|
||||
|
||||
// if the path is empty this path is just the name
|
||||
if tq.pp == "" {
|
||||
fi.Path = fi.Name
|
||||
} else {
|
||||
fi.Path = tq.pp + "." + fi.Name
|
||||
}
|
||||
|
||||
// skip unexported fields
|
||||
if len(f.PkgPath) != 0 && !f.Anonymous {
|
||||
continue
|
||||
}
|
||||
|
||||
// bfs search of anonymous embedded structs
|
||||
if f.Anonymous {
|
||||
pp := tq.pp
|
||||
if tag != "" {
|
||||
pp = fi.Path
|
||||
}
|
||||
|
||||
fi.Embedded = true
|
||||
fi.Index = apnd(tq.fi.Index, fieldPos)
|
||||
nChildren := 0
|
||||
ft := Deref(f.Type)
|
||||
if ft.Kind() == reflect.Struct {
|
||||
nChildren = ft.NumField()
|
||||
}
|
||||
fi.Children = make([]*FieldInfo, nChildren)
|
||||
queue = append(queue, typeQueue{Deref(f.Type), &fi, pp})
|
||||
} else if fi.Zero.Kind() == reflect.Struct || (fi.Zero.Kind() == reflect.Ptr && fi.Zero.Type().Elem().Kind() == reflect.Struct) {
|
||||
fi.Index = apnd(tq.fi.Index, fieldPos)
|
||||
fi.Children = make([]*FieldInfo, Deref(f.Type).NumField())
|
||||
queue = append(queue, typeQueue{Deref(f.Type), &fi, fi.Path})
|
||||
}
|
||||
|
||||
fi.Index = apnd(tq.fi.Index, fieldPos)
|
||||
fi.Parent = tq.fi
|
||||
tq.fi.Children[fieldPos] = &fi
|
||||
m = append(m, &fi)
|
||||
}
|
||||
}
|
||||
|
||||
flds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}}
|
||||
for _, fi := range flds.Index {
|
||||
flds.Paths[fi.Path] = fi
|
||||
if fi.Name != "" && !fi.Embedded {
|
||||
flds.Names[fi.Path] = fi
|
||||
}
|
||||
}
|
||||
|
||||
return flds
|
||||
}
|
905
vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go
generated
vendored
Normal file
905
vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go
generated
vendored
Normal file
@ -0,0 +1,905 @@
|
||||
package reflectx
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func ival(v reflect.Value) int {
|
||||
return v.Interface().(int)
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
type Foo struct {
|
||||
A int
|
||||
B int
|
||||
C int
|
||||
}
|
||||
|
||||
f := Foo{1, 2, 3}
|
||||
fv := reflect.ValueOf(f)
|
||||
m := NewMapperFunc("", func(s string) string { return s })
|
||||
|
||||
v := m.FieldByName(fv, "A")
|
||||
if ival(v) != f.A {
|
||||
t.Errorf("Expecting %d, got %d", ival(v), f.A)
|
||||
}
|
||||
v = m.FieldByName(fv, "B")
|
||||
if ival(v) != f.B {
|
||||
t.Errorf("Expecting %d, got %d", f.B, ival(v))
|
||||
}
|
||||
v = m.FieldByName(fv, "C")
|
||||
if ival(v) != f.C {
|
||||
t.Errorf("Expecting %d, got %d", f.C, ival(v))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicEmbedded(t *testing.T) {
|
||||
type Foo struct {
|
||||
A int
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
Foo // `db:""` is implied for an embedded struct
|
||||
B int
|
||||
C int `db:"-"`
|
||||
}
|
||||
|
||||
type Baz struct {
|
||||
A int
|
||||
Bar `db:"Bar"`
|
||||
}
|
||||
|
||||
m := NewMapperFunc("db", func(s string) string { return s })
|
||||
|
||||
z := Baz{}
|
||||
z.A = 1
|
||||
z.B = 2
|
||||
z.C = 4
|
||||
z.Bar.Foo.A = 3
|
||||
|
||||
zv := reflect.ValueOf(z)
|
||||
fields := m.TypeMap(reflect.TypeOf(z))
|
||||
|
||||
if len(fields.Index) != 5 {
|
||||
t.Errorf("Expecting 5 fields")
|
||||
}
|
||||
|
||||
// for _, fi := range fields.Index {
|
||||
// log.Println(fi)
|
||||
// }
|
||||
|
||||
v := m.FieldByName(zv, "A")
|
||||
if ival(v) != z.A {
|
||||
t.Errorf("Expecting %d, got %d", z.A, ival(v))
|
||||
}
|
||||
v = m.FieldByName(zv, "Bar.B")
|
||||
if ival(v) != z.Bar.B {
|
||||
t.Errorf("Expecting %d, got %d", z.Bar.B, ival(v))
|
||||
}
|
||||
v = m.FieldByName(zv, "Bar.A")
|
||||
if ival(v) != z.Bar.Foo.A {
|
||||
t.Errorf("Expecting %d, got %d", z.Bar.Foo.A, ival(v))
|
||||
}
|
||||
v = m.FieldByName(zv, "Bar.C")
|
||||
if _, ok := v.Interface().(int); ok {
|
||||
t.Errorf("Expecting Bar.C to not exist")
|
||||
}
|
||||
|
||||
fi := fields.GetByPath("Bar.C")
|
||||
if fi != nil {
|
||||
t.Errorf("Bar.C should not exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmbeddedSimple(t *testing.T) {
|
||||
type UUID [16]byte
|
||||
type MyID struct {
|
||||
UUID
|
||||
}
|
||||
type Item struct {
|
||||
ID MyID
|
||||
}
|
||||
z := Item{}
|
||||
|
||||
m := NewMapper("db")
|
||||
m.TypeMap(reflect.TypeOf(z))
|
||||
}
|
||||
|
||||
func TestBasicEmbeddedWithTags(t *testing.T) {
|
||||
type Foo struct {
|
||||
A int `db:"a"`
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
Foo // `db:""` is implied for an embedded struct
|
||||
B int `db:"b"`
|
||||
}
|
||||
|
||||
type Baz struct {
|
||||
A int `db:"a"`
|
||||
Bar // `db:""` is implied for an embedded struct
|
||||
}
|
||||
|
||||
m := NewMapper("db")
|
||||
|
||||
z := Baz{}
|
||||
z.A = 1
|
||||
z.B = 2
|
||||
z.Bar.Foo.A = 3
|
||||
|
||||
zv := reflect.ValueOf(z)
|
||||
fields := m.TypeMap(reflect.TypeOf(z))
|
||||
|
||||
if len(fields.Index) != 5 {
|
||||
t.Errorf("Expecting 5 fields")
|
||||
}
|
||||
|
||||
// for _, fi := range fields.index {
|
||||
// log.Println(fi)
|
||||
// }
|
||||
|
||||
v := m.FieldByName(zv, "a")
|
||||
if ival(v) != z.Bar.Foo.A { // the dominant field
|
||||
t.Errorf("Expecting %d, got %d", z.Bar.Foo.A, ival(v))
|
||||
}
|
||||
v = m.FieldByName(zv, "b")
|
||||
if ival(v) != z.B {
|
||||
t.Errorf("Expecting %d, got %d", z.B, ival(v))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlatTags(t *testing.T) {
|
||||
m := NewMapper("db")
|
||||
|
||||
type Asset struct {
|
||||
Title string `db:"title"`
|
||||
}
|
||||
type Post struct {
|
||||
Author string `db:"author,required"`
|
||||
Asset Asset `db:""`
|
||||
}
|
||||
// Post columns: (author title)
|
||||
|
||||
post := Post{Author: "Joe", Asset: Asset{Title: "Hello"}}
|
||||
pv := reflect.ValueOf(post)
|
||||
|
||||
v := m.FieldByName(pv, "author")
|
||||
if v.Interface().(string) != post.Author {
|
||||
t.Errorf("Expecting %s, got %s", post.Author, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "title")
|
||||
if v.Interface().(string) != post.Asset.Title {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset.Title, v.Interface().(string))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedStruct(t *testing.T) {
|
||||
m := NewMapper("db")
|
||||
|
||||
type Details struct {
|
||||
Active bool `db:"active"`
|
||||
}
|
||||
type Asset struct {
|
||||
Title string `db:"title"`
|
||||
Details Details `db:"details"`
|
||||
}
|
||||
type Post struct {
|
||||
Author string `db:"author,required"`
|
||||
Asset `db:"asset"`
|
||||
}
|
||||
// Post columns: (author asset.title asset.details.active)
|
||||
|
||||
post := Post{
|
||||
Author: "Joe",
|
||||
Asset: Asset{Title: "Hello", Details: Details{Active: true}},
|
||||
}
|
||||
pv := reflect.ValueOf(post)
|
||||
|
||||
v := m.FieldByName(pv, "author")
|
||||
if v.Interface().(string) != post.Author {
|
||||
t.Errorf("Expecting %s, got %s", post.Author, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "title")
|
||||
if _, ok := v.Interface().(string); ok {
|
||||
t.Errorf("Expecting field to not exist")
|
||||
}
|
||||
v = m.FieldByName(pv, "asset.title")
|
||||
if v.Interface().(string) != post.Asset.Title {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset.Title, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "asset.details.active")
|
||||
if v.Interface().(bool) != post.Asset.Details.Active {
|
||||
t.Errorf("Expecting %v, got %v", post.Asset.Details.Active, v.Interface().(bool))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInlineStruct(t *testing.T) {
|
||||
m := NewMapperTagFunc("db", strings.ToLower, nil)
|
||||
|
||||
type Employee struct {
|
||||
Name string
|
||||
ID int
|
||||
}
|
||||
type Boss Employee
|
||||
type person struct {
|
||||
Employee `db:"employee"`
|
||||
Boss `db:"boss"`
|
||||
}
|
||||
// employees columns: (employee.name employee.id boss.name boss.id)
|
||||
|
||||
em := person{Employee: Employee{Name: "Joe", ID: 2}, Boss: Boss{Name: "Dick", ID: 1}}
|
||||
ev := reflect.ValueOf(em)
|
||||
|
||||
fields := m.TypeMap(reflect.TypeOf(em))
|
||||
if len(fields.Index) != 6 {
|
||||
t.Errorf("Expecting 6 fields")
|
||||
}
|
||||
|
||||
v := m.FieldByName(ev, "employee.name")
|
||||
if v.Interface().(string) != em.Employee.Name {
|
||||
t.Errorf("Expecting %s, got %s", em.Employee.Name, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(ev, "boss.id")
|
||||
if ival(v) != em.Boss.ID {
|
||||
t.Errorf("Expecting %v, got %v", em.Boss.ID, ival(v))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecursiveStruct(t *testing.T) {
|
||||
type Person struct {
|
||||
Parent *Person
|
||||
}
|
||||
m := NewMapperFunc("db", strings.ToLower)
|
||||
var p *Person
|
||||
m.TypeMap(reflect.TypeOf(p))
|
||||
}
|
||||
|
||||
func TestFieldsEmbedded(t *testing.T) {
|
||||
m := NewMapper("db")
|
||||
|
||||
type Person struct {
|
||||
Name string `db:"name,size=64"`
|
||||
}
|
||||
type Place struct {
|
||||
Name string `db:"name"`
|
||||
}
|
||||
type Article struct {
|
||||
Title string `db:"title"`
|
||||
}
|
||||
type PP struct {
|
||||
Person `db:"person,required"`
|
||||
Place `db:",someflag"`
|
||||
Article `db:",required"`
|
||||
}
|
||||
// PP columns: (person.name name title)
|
||||
|
||||
pp := PP{}
|
||||
pp.Person.Name = "Peter"
|
||||
pp.Place.Name = "Toronto"
|
||||
pp.Article.Title = "Best city ever"
|
||||
|
||||
fields := m.TypeMap(reflect.TypeOf(pp))
|
||||
// for i, f := range fields {
|
||||
// log.Println(i, f)
|
||||
// }
|
||||
|
||||
ppv := reflect.ValueOf(pp)
|
||||
|
||||
v := m.FieldByName(ppv, "person.name")
|
||||
if v.Interface().(string) != pp.Person.Name {
|
||||
t.Errorf("Expecting %s, got %s", pp.Person.Name, v.Interface().(string))
|
||||
}
|
||||
|
||||
v = m.FieldByName(ppv, "name")
|
||||
if v.Interface().(string) != pp.Place.Name {
|
||||
t.Errorf("Expecting %s, got %s", pp.Place.Name, v.Interface().(string))
|
||||
}
|
||||
|
||||
v = m.FieldByName(ppv, "title")
|
||||
if v.Interface().(string) != pp.Article.Title {
|
||||
t.Errorf("Expecting %s, got %s", pp.Article.Title, v.Interface().(string))
|
||||
}
|
||||
|
||||
fi := fields.GetByPath("person")
|
||||
if _, ok := fi.Options["required"]; !ok {
|
||||
t.Errorf("Expecting required option to be set")
|
||||
}
|
||||
if !fi.Embedded {
|
||||
t.Errorf("Expecting field to be embedded")
|
||||
}
|
||||
if len(fi.Index) != 1 || fi.Index[0] != 0 {
|
||||
t.Errorf("Expecting index to be [0]")
|
||||
}
|
||||
|
||||
fi = fields.GetByPath("person.name")
|
||||
if fi == nil {
|
||||
t.Errorf("Expecting person.name to exist")
|
||||
}
|
||||
if fi.Path != "person.name" {
|
||||
t.Errorf("Expecting %s, got %s", "person.name", fi.Path)
|
||||
}
|
||||
if fi.Options["size"] != "64" {
|
||||
t.Errorf("Expecting %s, got %s", "64", fi.Options["size"])
|
||||
}
|
||||
|
||||
fi = fields.GetByTraversal([]int{1, 0})
|
||||
if fi == nil {
|
||||
t.Errorf("Expecting traveral to exist")
|
||||
}
|
||||
if fi.Path != "name" {
|
||||
t.Errorf("Expecting %s, got %s", "name", fi.Path)
|
||||
}
|
||||
|
||||
fi = fields.GetByTraversal([]int{2})
|
||||
if fi == nil {
|
||||
t.Errorf("Expecting traversal to exist")
|
||||
}
|
||||
if _, ok := fi.Options["required"]; !ok {
|
||||
t.Errorf("Expecting required option to be set")
|
||||
}
|
||||
|
||||
trs := m.TraversalsByName(reflect.TypeOf(pp), []string{"person.name", "name", "title"})
|
||||
if !reflect.DeepEqual(trs, [][]int{{0, 0}, {1, 0}, {2, 0}}) {
|
||||
t.Errorf("Expecting traversal: %v", trs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPtrFields(t *testing.T) {
|
||||
m := NewMapperTagFunc("db", strings.ToLower, nil)
|
||||
type Asset struct {
|
||||
Title string
|
||||
}
|
||||
type Post struct {
|
||||
*Asset `db:"asset"`
|
||||
Author string
|
||||
}
|
||||
|
||||
post := &Post{Author: "Joe", Asset: &Asset{Title: "Hiyo"}}
|
||||
pv := reflect.ValueOf(post)
|
||||
|
||||
fields := m.TypeMap(reflect.TypeOf(post))
|
||||
if len(fields.Index) != 3 {
|
||||
t.Errorf("Expecting 3 fields")
|
||||
}
|
||||
|
||||
v := m.FieldByName(pv, "asset.title")
|
||||
if v.Interface().(string) != post.Asset.Title {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset.Title, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "author")
|
||||
if v.Interface().(string) != post.Author {
|
||||
t.Errorf("Expecting %s, got %s", post.Author, v.Interface().(string))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedPtrFields(t *testing.T) {
|
||||
m := NewMapperTagFunc("db", strings.ToLower, nil)
|
||||
|
||||
type User struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type Asset struct {
|
||||
Title string
|
||||
|
||||
Owner *User `db:"owner"`
|
||||
}
|
||||
type Post struct {
|
||||
Author string
|
||||
|
||||
Asset1 *Asset `db:"asset1"`
|
||||
Asset2 *Asset `db:"asset2"`
|
||||
}
|
||||
|
||||
post := &Post{Author: "Joe", Asset1: &Asset{Title: "Hiyo", Owner: &User{"Username"}}} // Let Asset2 be nil
|
||||
pv := reflect.ValueOf(post)
|
||||
|
||||
fields := m.TypeMap(reflect.TypeOf(post))
|
||||
if len(fields.Index) != 9 {
|
||||
t.Errorf("Expecting 9 fields")
|
||||
}
|
||||
|
||||
v := m.FieldByName(pv, "asset1.title")
|
||||
if v.Interface().(string) != post.Asset1.Title {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset1.Title, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "asset1.owner.name")
|
||||
if v.Interface().(string) != post.Asset1.Owner.Name {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset1.Owner.Name, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "asset2.title")
|
||||
if v.Interface().(string) != post.Asset2.Title {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset2.Title, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "asset2.owner.name")
|
||||
if v.Interface().(string) != post.Asset2.Owner.Name {
|
||||
t.Errorf("Expecting %s, got %s", post.Asset2.Owner.Name, v.Interface().(string))
|
||||
}
|
||||
v = m.FieldByName(pv, "author")
|
||||
if v.Interface().(string) != post.Author {
|
||||
t.Errorf("Expecting %s, got %s", post.Author, v.Interface().(string))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldMap(t *testing.T) {
|
||||
type Foo struct {
|
||||
A int
|
||||
B int
|
||||
C int
|
||||
}
|
||||
|
||||
f := Foo{1, 2, 3}
|
||||
m := NewMapperFunc("db", strings.ToLower)
|
||||
|
||||
fm := m.FieldMap(reflect.ValueOf(f))
|
||||
|
||||
if len(fm) != 3 {
|
||||
t.Errorf("Expecting %d keys, got %d", 3, len(fm))
|
||||
}
|
||||
if fm["a"].Interface().(int) != 1 {
|
||||
t.Errorf("Expecting %d, got %d", 1, ival(fm["a"]))
|
||||
}
|
||||
if fm["b"].Interface().(int) != 2 {
|
||||
t.Errorf("Expecting %d, got %d", 2, ival(fm["b"]))
|
||||
}
|
||||
if fm["c"].Interface().(int) != 3 {
|
||||
t.Errorf("Expecting %d, got %d", 3, ival(fm["c"]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagNameMapping(t *testing.T) {
|
||||
type Strategy struct {
|
||||
StrategyID string `protobuf:"bytes,1,opt,name=strategy_id" json:"strategy_id,omitempty"`
|
||||
StrategyName string
|
||||
}
|
||||
|
||||
m := NewMapperTagFunc("json", strings.ToUpper, func(value string) string {
|
||||
if strings.Contains(value, ",") {
|
||||
return strings.Split(value, ",")[0]
|
||||
}
|
||||
return value
|
||||
})
|
||||
strategy := Strategy{"1", "Alpah"}
|
||||
mapping := m.TypeMap(reflect.TypeOf(strategy))
|
||||
|
||||
for _, key := range []string{"strategy_id", "STRATEGYNAME"} {
|
||||
if fi := mapping.GetByPath(key); fi == nil {
|
||||
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapping(t *testing.T) {
|
||||
type Person struct {
|
||||
ID int
|
||||
Name string
|
||||
WearsGlasses bool `db:"wears_glasses"`
|
||||
}
|
||||
|
||||
m := NewMapperFunc("db", strings.ToLower)
|
||||
p := Person{1, "Jason", true}
|
||||
mapping := m.TypeMap(reflect.TypeOf(p))
|
||||
|
||||
for _, key := range []string{"id", "name", "wears_glasses"} {
|
||||
if fi := mapping.GetByPath(key); fi == nil {
|
||||
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||||
}
|
||||
}
|
||||
|
||||
type SportsPerson struct {
|
||||
Weight int
|
||||
Age int
|
||||
Person
|
||||
}
|
||||
s := SportsPerson{Weight: 100, Age: 30, Person: p}
|
||||
mapping = m.TypeMap(reflect.TypeOf(s))
|
||||
for _, key := range []string{"id", "name", "wears_glasses", "weight", "age"} {
|
||||
if fi := mapping.GetByPath(key); fi == nil {
|
||||
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||||
}
|
||||
}
|
||||
|
||||
type RugbyPlayer struct {
|
||||
Position int
|
||||
IsIntense bool `db:"is_intense"`
|
||||
IsAllBlack bool `db:"-"`
|
||||
SportsPerson
|
||||
}
|
||||
r := RugbyPlayer{12, true, false, s}
|
||||
mapping = m.TypeMap(reflect.TypeOf(r))
|
||||
for _, key := range []string{"id", "name", "wears_glasses", "weight", "age", "position", "is_intense"} {
|
||||
if fi := mapping.GetByPath(key); fi == nil {
|
||||
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||||
}
|
||||
}
|
||||
|
||||
if fi := mapping.GetByPath("isallblack"); fi != nil {
|
||||
t.Errorf("Expecting to ignore `IsAllBlack` field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetByTraversal(t *testing.T) {
|
||||
type C struct {
|
||||
C0 int
|
||||
C1 int
|
||||
}
|
||||
type B struct {
|
||||
B0 string
|
||||
B1 *C
|
||||
}
|
||||
type A struct {
|
||||
A0 int
|
||||
A1 B
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Index []int
|
||||
ExpectedName string
|
||||
ExpectNil bool
|
||||
}{
|
||||
{
|
||||
Index: []int{0},
|
||||
ExpectedName: "A0",
|
||||
},
|
||||
{
|
||||
Index: []int{1, 0},
|
||||
ExpectedName: "B0",
|
||||
},
|
||||
{
|
||||
Index: []int{1, 1, 1},
|
||||
ExpectedName: "C1",
|
||||
},
|
||||
{
|
||||
Index: []int{3, 4, 5},
|
||||
ExpectNil: true,
|
||||
},
|
||||
{
|
||||
Index: []int{},
|
||||
ExpectNil: true,
|
||||
},
|
||||
{
|
||||
Index: nil,
|
||||
ExpectNil: true,
|
||||
},
|
||||
}
|
||||
|
||||
m := NewMapperFunc("db", func(n string) string { return n })
|
||||
tm := m.TypeMap(reflect.TypeOf(A{}))
|
||||
|
||||
for i, tc := range testCases {
|
||||
fi := tm.GetByTraversal(tc.Index)
|
||||
if tc.ExpectNil {
|
||||
if fi != nil {
|
||||
t.Errorf("%d: expected nil, got %v", i, fi)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if fi == nil {
|
||||
t.Errorf("%d: expected %s, got nil", i, tc.ExpectedName)
|
||||
continue
|
||||
}
|
||||
|
||||
if fi.Name != tc.ExpectedName {
|
||||
t.Errorf("%d: expected %s, got %s", i, tc.ExpectedName, fi.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestMapperMethodsByName tests Mapper methods FieldByName and TraversalsByName
|
||||
func TestMapperMethodsByName(t *testing.T) {
|
||||
type C struct {
|
||||
C0 string
|
||||
C1 int
|
||||
}
|
||||
type B struct {
|
||||
B0 *C `db:"B0"`
|
||||
B1 C `db:"B1"`
|
||||
B2 string `db:"B2"`
|
||||
}
|
||||
type A struct {
|
||||
A0 *B `db:"A0"`
|
||||
B `db:"A1"`
|
||||
A2 int
|
||||
a3 int
|
||||
}
|
||||
|
||||
val := &A{
|
||||
A0: &B{
|
||||
B0: &C{C0: "0", C1: 1},
|
||||
B1: C{C0: "2", C1: 3},
|
||||
B2: "4",
|
||||
},
|
||||
B: B{
|
||||
B0: nil,
|
||||
B1: C{C0: "5", C1: 6},
|
||||
B2: "7",
|
||||
},
|
||||
A2: 8,
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
ExpectInvalid bool
|
||||
ExpectedValue interface{}
|
||||
ExpectedIndexes []int
|
||||
}{
|
||||
{
|
||||
Name: "A0.B0.C0",
|
||||
ExpectedValue: "0",
|
||||
ExpectedIndexes: []int{0, 0, 0},
|
||||
},
|
||||
{
|
||||
Name: "A0.B0.C1",
|
||||
ExpectedValue: 1,
|
||||
ExpectedIndexes: []int{0, 0, 1},
|
||||
},
|
||||
{
|
||||
Name: "A0.B1.C0",
|
||||
ExpectedValue: "2",
|
||||
ExpectedIndexes: []int{0, 1, 0},
|
||||
},
|
||||
{
|
||||
Name: "A0.B1.C1",
|
||||
ExpectedValue: 3,
|
||||
ExpectedIndexes: []int{0, 1, 1},
|
||||
},
|
||||
{
|
||||
Name: "A0.B2",
|
||||
ExpectedValue: "4",
|
||||
ExpectedIndexes: []int{0, 2},
|
||||
},
|
||||
{
|
||||
Name: "A1.B0.C0",
|
||||
ExpectedValue: "",
|
||||
ExpectedIndexes: []int{1, 0, 0},
|
||||
},
|
||||
{
|
||||
Name: "A1.B0.C1",
|
||||
ExpectedValue: 0,
|
||||
ExpectedIndexes: []int{1, 0, 1},
|
||||
},
|
||||
{
|
||||
Name: "A1.B1.C0",
|
||||
ExpectedValue: "5",
|
||||
ExpectedIndexes: []int{1, 1, 0},
|
||||
},
|
||||
{
|
||||
Name: "A1.B1.C1",
|
||||
ExpectedValue: 6,
|
||||
ExpectedIndexes: []int{1, 1, 1},
|
||||
},
|
||||
{
|
||||
Name: "A1.B2",
|
||||
ExpectedValue: "7",
|
||||
ExpectedIndexes: []int{1, 2},
|
||||
},
|
||||
{
|
||||
Name: "A2",
|
||||
ExpectedValue: 8,
|
||||
ExpectedIndexes: []int{2},
|
||||
},
|
||||
{
|
||||
Name: "XYZ",
|
||||
ExpectInvalid: true,
|
||||
ExpectedIndexes: []int{},
|
||||
},
|
||||
{
|
||||
Name: "a3",
|
||||
ExpectInvalid: true,
|
||||
ExpectedIndexes: []int{},
|
||||
},
|
||||
}
|
||||
|
||||
// build the names array from the test cases
|
||||
names := make([]string, len(testCases))
|
||||
for i, tc := range testCases {
|
||||
names[i] = tc.Name
|
||||
}
|
||||
m := NewMapperFunc("db", func(n string) string { return n })
|
||||
v := reflect.ValueOf(val)
|
||||
values := m.FieldsByName(v, names)
|
||||
if len(values) != len(testCases) {
|
||||
t.Errorf("expected %d values, got %d", len(testCases), len(values))
|
||||
t.FailNow()
|
||||
}
|
||||
indexes := m.TraversalsByName(v.Type(), names)
|
||||
if len(indexes) != len(testCases) {
|
||||
t.Errorf("expected %d traversals, got %d", len(testCases), len(indexes))
|
||||
t.FailNow()
|
||||
}
|
||||
for i, val := range values {
|
||||
tc := testCases[i]
|
||||
traversal := indexes[i]
|
||||
if !reflect.DeepEqual(tc.ExpectedIndexes, traversal) {
|
||||
t.Errorf("expected %v, got %v", tc.ExpectedIndexes, traversal)
|
||||
t.FailNow()
|
||||
}
|
||||
val = reflect.Indirect(val)
|
||||
if tc.ExpectInvalid {
|
||||
if val.IsValid() {
|
||||
t.Errorf("%d: expected zero value, got %v", i, val)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !val.IsValid() {
|
||||
t.Errorf("%d: expected valid value, got %v", i, val)
|
||||
continue
|
||||
}
|
||||
actualValue := reflect.Indirect(val).Interface()
|
||||
if !reflect.DeepEqual(tc.ExpectedValue, actualValue) {
|
||||
t.Errorf("%d: expected %v, got %v", i, tc.ExpectedValue, actualValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldByIndexes(t *testing.T) {
|
||||
type C struct {
|
||||
C0 bool
|
||||
C1 string
|
||||
C2 int
|
||||
C3 map[string]int
|
||||
}
|
||||
type B struct {
|
||||
B1 C
|
||||
B2 *C
|
||||
}
|
||||
type A struct {
|
||||
A1 B
|
||||
A2 *B
|
||||
}
|
||||
testCases := []struct {
|
||||
value interface{}
|
||||
indexes []int
|
||||
expectedValue interface{}
|
||||
readOnly bool
|
||||
}{
|
||||
{
|
||||
value: A{
|
||||
A1: B{B1: C{C0: true}},
|
||||
},
|
||||
indexes: []int{0, 0, 0},
|
||||
expectedValue: true,
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
value: A{
|
||||
A2: &B{B2: &C{C1: "answer"}},
|
||||
},
|
||||
indexes: []int{1, 1, 1},
|
||||
expectedValue: "answer",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
value: &A{},
|
||||
indexes: []int{1, 1, 3},
|
||||
expectedValue: map[string]int{},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
checkResults := func(v reflect.Value) {
|
||||
if tc.expectedValue == nil {
|
||||
if !v.IsNil() {
|
||||
t.Errorf("%d: expected nil, actual %v", i, v.Interface())
|
||||
}
|
||||
} else {
|
||||
if !reflect.DeepEqual(tc.expectedValue, v.Interface()) {
|
||||
t.Errorf("%d: expected %v, actual %v", i, tc.expectedValue, v.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkResults(FieldByIndexes(reflect.ValueOf(tc.value), tc.indexes))
|
||||
if tc.readOnly {
|
||||
checkResults(FieldByIndexesReadOnly(reflect.ValueOf(tc.value), tc.indexes))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMustBe(t *testing.T) {
|
||||
typ := reflect.TypeOf(E1{})
|
||||
mustBe(typ, reflect.Struct)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
valueErr, ok := r.(*reflect.ValueError)
|
||||
if !ok {
|
||||
t.Errorf("unexpected Method: %s", valueErr.Method)
|
||||
t.Error("expected panic with *reflect.ValueError")
|
||||
return
|
||||
}
|
||||
if valueErr.Method != "github.com/jmoiron/sqlx/reflectx.TestMustBe" {
|
||||
}
|
||||
if valueErr.Kind != reflect.String {
|
||||
t.Errorf("unexpected Kind: %s", valueErr.Kind)
|
||||
}
|
||||
} else {
|
||||
t.Error("expected panic")
|
||||
}
|
||||
}()
|
||||
|
||||
typ = reflect.TypeOf("string")
|
||||
mustBe(typ, reflect.Struct)
|
||||
t.Error("got here, didn't expect to")
|
||||
}
|
||||
|
||||
type E1 struct {
|
||||
A int
|
||||
}
|
||||
type E2 struct {
|
||||
E1
|
||||
B int
|
||||
}
|
||||
type E3 struct {
|
||||
E2
|
||||
C int
|
||||
}
|
||||
type E4 struct {
|
||||
E3
|
||||
D int
|
||||
}
|
||||
|
||||
func BenchmarkFieldNameL1(b *testing.B) {
|
||||
e4 := E4{D: 1}
|
||||
for i := 0; i < b.N; i++ {
|
||||
v := reflect.ValueOf(e4)
|
||||
f := v.FieldByName("D")
|
||||
if f.Interface().(int) != 1 {
|
||||
b.Fatal("Wrong value.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFieldNameL4(b *testing.B) {
|
||||
e4 := E4{}
|
||||
e4.A = 1
|
||||
for i := 0; i < b.N; i++ {
|
||||
v := reflect.ValueOf(e4)
|
||||
f := v.FieldByName("A")
|
||||
if f.Interface().(int) != 1 {
|
||||
b.Fatal("Wrong value.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFieldPosL1(b *testing.B) {
|
||||
e4 := E4{D: 1}
|
||||
for i := 0; i < b.N; i++ {
|
||||
v := reflect.ValueOf(e4)
|
||||
f := v.Field(1)
|
||||
if f.Interface().(int) != 1 {
|
||||
b.Fatal("Wrong value.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFieldPosL4(b *testing.B) {
|
||||
e4 := E4{}
|
||||
e4.A = 1
|
||||
for i := 0; i < b.N; i++ {
|
||||
v := reflect.ValueOf(e4)
|
||||
f := v.Field(0)
|
||||
f = f.Field(0)
|
||||
f = f.Field(0)
|
||||
f = f.Field(0)
|
||||
if f.Interface().(int) != 1 {
|
||||
b.Fatal("Wrong value.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFieldByIndexL4(b *testing.B) {
|
||||
e4 := E4{}
|
||||
e4.A = 1
|
||||
idx := []int{0, 0, 0, 0}
|
||||
for i := 0; i < b.N; i++ {
|
||||
v := reflect.ValueOf(e4)
|
||||
f := FieldByIndexes(v, idx)
|
||||
if f.Interface().(int) != 1 {
|
||||
b.Fatal("Wrong value.")
|
||||
}
|
||||
}
|
||||
}
|
1035
vendor/github.com/jmoiron/sqlx/sqlx.go
generated
vendored
Normal file
1035
vendor/github.com/jmoiron/sqlx/sqlx.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
335
vendor/github.com/jmoiron/sqlx/sqlx_context.go
generated
vendored
Normal file
335
vendor/github.com/jmoiron/sqlx/sqlx_context.go
generated
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
// +build go1.8
|
||||
|
||||
package sqlx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ConnectContext to a database and verify with a ping.
|
||||
func ConnectContext(ctx context.Context, driverName, dataSourceName string) (*DB, error) {
|
||||
db, err := Open(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return db, err
|
||||
}
|
||||
err = db.PingContext(ctx)
|
||||
return db, err
|
||||
}
|
||||
|
||||
// QueryerContext is an interface used by GetContext and SelectContext
|
||||
type QueryerContext interface {
|
||||
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
|
||||
QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error)
|
||||
QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row
|
||||
}
|
||||
|
||||
// PreparerContext is an interface used by PreparexContext.
|
||||
type PreparerContext interface {
|
||||
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
|
||||
}
|
||||
|
||||
// ExecerContext is an interface used by MustExecContext and LoadFileContext
|
||||
type ExecerContext interface {
|
||||
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
// ExtContext is a union interface which can bind, query, and exec, with Context
|
||||
// used by NamedQueryContext and NamedExecContext.
|
||||
type ExtContext interface {
|
||||
binder
|
||||
QueryerContext
|
||||
ExecerContext
|
||||
}
|
||||
|
||||
// SelectContext executes a query using the provided Queryer, and StructScans
|
||||
// each row into dest, which must be a slice. If the slice elements are
|
||||
// scannable, then the result set must have only one column. Otherwise,
|
||||
// StructScan is used. The *sql.Rows are closed automatically.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func SelectContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {
|
||||
rows, err := q.QueryxContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if something happens here, we want to make sure the rows are Closed
|
||||
defer rows.Close()
|
||||
return scanAll(rows, dest, false)
|
||||
}
|
||||
|
||||
// PreparexContext prepares a statement.
|
||||
//
|
||||
// The provided context is used for the preparation of the statement, not for
|
||||
// the execution of the statement.
|
||||
func PreparexContext(ctx context.Context, p PreparerContext, query string) (*Stmt, error) {
|
||||
s, err := p.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err
|
||||
}
|
||||
|
||||
// GetContext does a QueryRow using the provided Queryer, and scans the
|
||||
// resulting row to dest. If dest is scannable, the result must only have one
|
||||
// column. Otherwise, StructScan is used. Get will return sql.ErrNoRows like
|
||||
// row.Scan would. Any placeholder parameters are replaced with supplied args.
|
||||
// An error is returned if the result set is empty.
|
||||
func GetContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {
|
||||
r := q.QueryRowxContext(ctx, query, args...)
|
||||
return r.scanAny(dest, false)
|
||||
}
|
||||
|
||||
// LoadFileContext exec's every statement in a file (as a single call to Exec).
|
||||
// LoadFileContext may return a nil *sql.Result if errors are encountered
|
||||
// locating or reading the file at path. LoadFile reads the entire file into
|
||||
// memory, so it is not suitable for loading large data dumps, but can be useful
|
||||
// for initializing schemas or loading indexes.
|
||||
//
|
||||
// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3
|
||||
// or the go-mysql-driver/mysql drivers; pq seems to be an exception here. Detecting
|
||||
// this by requiring something with DriverName() and then attempting to split the
|
||||
// queries will be difficult to get right, and its current driver-specific behavior
|
||||
// is deemed at least not complex in its incorrectness.
|
||||
func LoadFileContext(ctx context.Context, e ExecerContext, path string) (*sql.Result, error) {
|
||||
realpath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contents, err := ioutil.ReadFile(realpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := e.ExecContext(ctx, string(contents))
|
||||
return &res, err
|
||||
}
|
||||
|
||||
// MustExecContext execs the query using e and panics if there was an error.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func MustExecContext(ctx context.Context, e ExecerContext, query string, args ...interface{}) sql.Result {
|
||||
res, err := e.ExecContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// PrepareNamedContext returns an sqlx.NamedStmt
|
||||
func (db *DB) PrepareNamedContext(ctx context.Context, query string) (*NamedStmt, error) {
|
||||
return prepareNamedContext(ctx, db, query)
|
||||
}
|
||||
|
||||
// NamedQueryContext using this DB.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (db *DB) NamedQueryContext(ctx context.Context, query string, arg interface{}) (*Rows, error) {
|
||||
return NamedQueryContext(ctx, db, query, arg)
|
||||
}
|
||||
|
||||
// NamedExecContext using this DB.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (db *DB) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) {
|
||||
return NamedExecContext(ctx, db, query, arg)
|
||||
}
|
||||
|
||||
// SelectContext using this DB.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (db *DB) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return SelectContext(ctx, db, dest, query, args...)
|
||||
}
|
||||
|
||||
// GetContext using this DB.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
// An error is returned if the result set is empty.
|
||||
func (db *DB) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return GetContext(ctx, db, dest, query, args...)
|
||||
}
|
||||
|
||||
// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt.
|
||||
//
|
||||
// The provided context is used for the preparation of the statement, not for
|
||||
// the execution of the statement.
|
||||
func (db *DB) PreparexContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
return PreparexContext(ctx, db, query)
|
||||
}
|
||||
|
||||
// QueryxContext queries the database and returns an *sqlx.Rows.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (db *DB) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
r, err := db.DB.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err
|
||||
}
|
||||
|
||||
// QueryRowxContext queries the database and returns an *sqlx.Row.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (db *DB) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := db.DB.QueryContext(ctx, query, args...)
|
||||
return &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper}
|
||||
}
|
||||
|
||||
// MustBeginTx starts a transaction, and panics on error. Returns an *sqlx.Tx instead
|
||||
// of an *sql.Tx.
|
||||
//
|
||||
// The provided context is used until the transaction is committed or rolled
|
||||
// back. If the context is canceled, the sql package will roll back the
|
||||
// transaction. Tx.Commit will return an error if the context provided to
|
||||
// MustBeginContext is canceled.
|
||||
func (db *DB) MustBeginTx(ctx context.Context, opts *sql.TxOptions) *Tx {
|
||||
tx, err := db.BeginTxx(ctx, opts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
||||
// MustExecContext (panic) runs MustExec using this database.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (db *DB) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result {
|
||||
return MustExecContext(ctx, db, query, args...)
|
||||
}
|
||||
|
||||
// BeginTxx begins a transaction and returns an *sqlx.Tx instead of an
|
||||
// *sql.Tx.
|
||||
//
|
||||
// The provided context is used until the transaction is committed or rolled
|
||||
// back. If the context is canceled, the sql package will roll back the
|
||||
// transaction. Tx.Commit will return an error if the context provided to
|
||||
// BeginxContext is canceled.
|
||||
func (db *DB) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||
tx, err := db.DB.BeginTx(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err
|
||||
}
|
||||
|
||||
// StmtxContext returns a version of the prepared statement which runs within a
|
||||
// transaction. Provided stmt can be either *sql.Stmt or *sqlx.Stmt.
|
||||
func (tx *Tx) StmtxContext(ctx context.Context, stmt interface{}) *Stmt {
|
||||
var s *sql.Stmt
|
||||
switch v := stmt.(type) {
|
||||
case Stmt:
|
||||
s = v.Stmt
|
||||
case *Stmt:
|
||||
s = v.Stmt
|
||||
case sql.Stmt:
|
||||
s = &v
|
||||
case *sql.Stmt:
|
||||
s = v
|
||||
default:
|
||||
panic(fmt.Sprintf("non-statement type %v passed to Stmtx", reflect.ValueOf(stmt).Type()))
|
||||
}
|
||||
return &Stmt{Stmt: tx.StmtContext(ctx, s), Mapper: tx.Mapper}
|
||||
}
|
||||
|
||||
// NamedStmtContext returns a version of the prepared statement which runs
|
||||
// within a transaction.
|
||||
func (tx *Tx) NamedStmtContext(ctx context.Context, stmt *NamedStmt) *NamedStmt {
|
||||
return &NamedStmt{
|
||||
QueryString: stmt.QueryString,
|
||||
Params: stmt.Params,
|
||||
Stmt: tx.StmtxContext(ctx, stmt.Stmt),
|
||||
}
|
||||
}
|
||||
|
||||
// MustExecContext runs MustExecContext within a transaction.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (tx *Tx) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result {
|
||||
return MustExecContext(ctx, tx, query, args...)
|
||||
}
|
||||
|
||||
// QueryxContext within a transaction and context.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (tx *Tx) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
r, err := tx.Tx.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err
|
||||
}
|
||||
|
||||
// SelectContext within a transaction and context.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (tx *Tx) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return SelectContext(ctx, tx, dest, query, args...)
|
||||
}
|
||||
|
||||
// GetContext within a transaction and context.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
// An error is returned if the result set is empty.
|
||||
func (tx *Tx) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return GetContext(ctx, tx, dest, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowxContext within a transaction and context.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (tx *Tx) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := tx.Tx.QueryContext(ctx, query, args...)
|
||||
return &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper}
|
||||
}
|
||||
|
||||
// NamedExecContext using this Tx.
|
||||
// Any named placeholder parameters are replaced with fields from arg.
|
||||
func (tx *Tx) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) {
|
||||
return NamedExecContext(ctx, tx, query, arg)
|
||||
}
|
||||
|
||||
// SelectContext using the prepared statement.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (s *Stmt) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error {
|
||||
return SelectContext(ctx, &qStmt{s}, dest, "", args...)
|
||||
}
|
||||
|
||||
// GetContext using the prepared statement.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
// An error is returned if the result set is empty.
|
||||
func (s *Stmt) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error {
|
||||
return GetContext(ctx, &qStmt{s}, dest, "", args...)
|
||||
}
|
||||
|
||||
// MustExecContext (panic) using this statement. Note that the query portion of
|
||||
// the error output will be blank, as Stmt does not expose its query.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (s *Stmt) MustExecContext(ctx context.Context, args ...interface{}) sql.Result {
|
||||
return MustExecContext(ctx, &qStmt{s}, "", args...)
|
||||
}
|
||||
|
||||
// QueryRowxContext using this statement.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (s *Stmt) QueryRowxContext(ctx context.Context, args ...interface{}) *Row {
|
||||
qs := &qStmt{s}
|
||||
return qs.QueryRowxContext(ctx, "", args...)
|
||||
}
|
||||
|
||||
// QueryxContext using this statement.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (s *Stmt) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) {
|
||||
qs := &qStmt{s}
|
||||
return qs.QueryxContext(ctx, "", args...)
|
||||
}
|
||||
|
||||
func (q *qStmt) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
return q.Stmt.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (q *qStmt) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
r, err := q.Stmt.QueryContext(ctx, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err
|
||||
}
|
||||
|
||||
func (q *qStmt) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := q.Stmt.QueryContext(ctx, args...)
|
||||
return &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}
|
||||
}
|
||||
|
||||
func (q *qStmt) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
return q.Stmt.ExecContext(ctx, args...)
|
||||
}
|
1344
vendor/github.com/jmoiron/sqlx/sqlx_context_test.go
generated
vendored
Normal file
1344
vendor/github.com/jmoiron/sqlx/sqlx_context_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1792
vendor/github.com/jmoiron/sqlx/sqlx_test.go
generated
vendored
Normal file
1792
vendor/github.com/jmoiron/sqlx/sqlx_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
vendor/github.com/jmoiron/sqlx/types/README.md
generated
vendored
Normal file
5
vendor/github.com/jmoiron/sqlx/types/README.md
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# types
|
||||
|
||||
The types package provides some useful types which implement the `sql.Scanner`
|
||||
and `driver.Valuer` interfaces, suitable for use as scan and value targets with
|
||||
database/sql.
|
172
vendor/github.com/jmoiron/sqlx/types/types.go
generated
vendored
Normal file
172
vendor/github.com/jmoiron/sqlx/types/types.go
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// GzippedText is a []byte which transparently gzips data being submitted to
|
||||
// a database and ungzips data being Scanned from a database.
|
||||
type GzippedText []byte
|
||||
|
||||
// Value implements the driver.Valuer interface, gzipping the raw value of
|
||||
// this GzippedText.
|
||||
func (g GzippedText) Value() (driver.Value, error) {
|
||||
b := make([]byte, 0, len(g))
|
||||
buf := bytes.NewBuffer(b)
|
||||
w := gzip.NewWriter(buf)
|
||||
w.Write(g)
|
||||
w.Close()
|
||||
return buf.Bytes(), nil
|
||||
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface, ungzipping the value coming off
|
||||
// the wire and storing the raw result in the GzippedText.
|
||||
func (g *GzippedText) Scan(src interface{}) error {
|
||||
var source []byte
|
||||
switch src.(type) {
|
||||
case string:
|
||||
source = []byte(src.(string))
|
||||
case []byte:
|
||||
source = src.([]byte)
|
||||
default:
|
||||
return errors.New("Incompatible type for GzippedText")
|
||||
}
|
||||
reader, err := gzip.NewReader(bytes.NewReader(source))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*g = GzippedText(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// JSONText is a json.RawMessage, which is a []byte underneath.
|
||||
// Value() validates the json format in the source, and returns an error if
|
||||
// the json is not valid. Scan does no validation. JSONText additionally
|
||||
// implements `Unmarshal`, which unmarshals the json within to an interface{}
|
||||
type JSONText json.RawMessage
|
||||
|
||||
var emptyJSON = JSONText("{}")
|
||||
|
||||
// MarshalJSON returns the *j as the JSON encoding of j.
|
||||
func (j JSONText) MarshalJSON() ([]byte, error) {
|
||||
if len(j) == 0 {
|
||||
return emptyJSON, nil
|
||||
}
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets *j to a copy of data
|
||||
func (j *JSONText) UnmarshalJSON(data []byte) error {
|
||||
if j == nil {
|
||||
return errors.New("JSONText: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
*j = append((*j)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns j as a value. This does a validating unmarshal into another
|
||||
// RawMessage. If j is invalid json, it returns an error.
|
||||
func (j JSONText) Value() (driver.Value, error) {
|
||||
var m json.RawMessage
|
||||
var err = j.Unmarshal(&m)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return []byte(j), nil
|
||||
}
|
||||
|
||||
// Scan stores the src in *j. No validation is done.
|
||||
func (j *JSONText) Scan(src interface{}) error {
|
||||
var source []byte
|
||||
switch t := src.(type) {
|
||||
case string:
|
||||
source = []byte(t)
|
||||
case []byte:
|
||||
if len(t) == 0 {
|
||||
source = emptyJSON
|
||||
} else {
|
||||
source = t
|
||||
}
|
||||
case nil:
|
||||
*j = emptyJSON
|
||||
default:
|
||||
return errors.New("Incompatible type for JSONText")
|
||||
}
|
||||
*j = JSONText(append((*j)[0:0], source...))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
|
||||
func (j *JSONText) Unmarshal(v interface{}) error {
|
||||
if len(*j) == 0 {
|
||||
*j = emptyJSON
|
||||
}
|
||||
return json.Unmarshal([]byte(*j), v)
|
||||
}
|
||||
|
||||
// String supports pretty printing for JSONText types.
|
||||
func (j JSONText) String() string {
|
||||
return string(j)
|
||||
}
|
||||
|
||||
// NullJSONText represents a JSONText that may be null.
|
||||
// NullJSONText implements the scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullJSONText struct {
|
||||
JSONText
|
||||
Valid bool // Valid is true if JSONText is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullJSONText) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.JSONText, n.Valid = emptyJSON, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return n.JSONText.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullJSONText) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.JSONText.Value()
|
||||
}
|
||||
|
||||
// BitBool is an implementation of a bool for the MySQL type BIT(1).
|
||||
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
|
||||
type BitBool bool
|
||||
|
||||
// Value implements the driver.Valuer interface,
|
||||
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
|
||||
func (b BitBool) Value() (driver.Value, error) {
|
||||
if b {
|
||||
return []byte{1}, nil
|
||||
}
|
||||
return []byte{0}, nil
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface,
|
||||
// and turns the bitfield incoming from MySQL into a BitBool
|
||||
func (b *BitBool) Scan(src interface{}) error {
|
||||
v, ok := src.([]byte)
|
||||
if !ok {
|
||||
return errors.New("bad []byte type assertion")
|
||||
}
|
||||
*b = v[0] == 1
|
||||
return nil
|
||||
}
|
127
vendor/github.com/jmoiron/sqlx/types/types_test.go
generated
vendored
Normal file
127
vendor/github.com/jmoiron/sqlx/types/types_test.go
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
package types
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGzipText(t *testing.T) {
|
||||
g := GzippedText("Hello, world")
|
||||
v, err := g.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
err = (&g).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
if string(g) != "Hello, world" {
|
||||
t.Errorf("Was expecting the string we sent in (Hello World), got %s", string(g))
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONText(t *testing.T) {
|
||||
j := JSONText(`{"foo": 1, "bar": 2}`)
|
||||
v, err := j.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
err = (&j).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
m := map[string]interface{}{}
|
||||
j.Unmarshal(&m)
|
||||
|
||||
if m["foo"].(float64) != 1 || m["bar"].(float64) != 2 {
|
||||
t.Errorf("Expected valid json but got some garbage instead? %#v", m)
|
||||
}
|
||||
|
||||
j = JSONText(`{"foo": 1, invalid, false}`)
|
||||
v, err = j.Value()
|
||||
if err == nil {
|
||||
t.Errorf("Was expecting invalid json to fail!")
|
||||
}
|
||||
|
||||
j = JSONText("")
|
||||
v, err = j.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
|
||||
err = (&j).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
|
||||
j = JSONText(nil)
|
||||
v, err = j.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
|
||||
err = (&j).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNullJSONText(t *testing.T) {
|
||||
j := NullJSONText{}
|
||||
err := j.Scan(`{"foo": 1, "bar": 2}`)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
v, err := j.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
err = (&j).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
m := map[string]interface{}{}
|
||||
j.Unmarshal(&m)
|
||||
|
||||
if m["foo"].(float64) != 1 || m["bar"].(float64) != 2 {
|
||||
t.Errorf("Expected valid json but got some garbage instead? %#v", m)
|
||||
}
|
||||
|
||||
j = NullJSONText{}
|
||||
err = j.Scan(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
if j.Valid != false {
|
||||
t.Errorf("Expected valid to be false, but got true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitBool(t *testing.T) {
|
||||
// Test true value
|
||||
var b BitBool = true
|
||||
|
||||
v, err := b.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Cannot return error")
|
||||
}
|
||||
err = (&b).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
if !b {
|
||||
t.Errorf("Was expecting the bool we sent in (true), got %v", b)
|
||||
}
|
||||
|
||||
// Test false value
|
||||
b = false
|
||||
|
||||
v, err = b.Value()
|
||||
if err != nil {
|
||||
t.Errorf("Cannot return error")
|
||||
}
|
||||
err = (&b).Scan(v)
|
||||
if err != nil {
|
||||
t.Errorf("Was not expecting an error")
|
||||
}
|
||||
if b {
|
||||
t.Errorf("Was expecting the bool we sent in (false), got %v", b)
|
||||
}
|
||||
}
|
32
vendor/github.com/mattn/go-gtk/.gitignore
generated
vendored
Normal file
32
vendor/github.com/mattn/go-gtk/.gitignore
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
*~
|
||||
_obj
|
||||
*.cgo?.*
|
||||
_cgo_*
|
||||
main
|
||||
*.exe
|
||||
tags
|
||||
|
||||
# example binaries
|
||||
example/action/action
|
||||
example/alignment/alignment
|
||||
example/arrow/arrow
|
||||
example/builder/builder
|
||||
example/clipboard/clipboard
|
||||
example/demo/demo
|
||||
example/dnd/dnd
|
||||
example/drawable/drawable
|
||||
example/event/event
|
||||
example/expander/expander
|
||||
example/iconview/iconview
|
||||
example/listview/listview
|
||||
example/locale/locale
|
||||
example/notebook/notebook
|
||||
example/number/number
|
||||
example/sourceview/sourceview
|
||||
example/spinbutton/spinbutton
|
||||
example/statusicon/statusicon
|
||||
example/table/table
|
||||
example/thread/thread
|
||||
example/toolbar/toolbar
|
||||
example/treeview/treeview
|
||||
example/twitterstream/twitterstream
|
4
vendor/github.com/mattn/go-gtk/.gitmodules
generated
vendored
Normal file
4
vendor/github.com/mattn/go-gtk/.gitmodules
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "docs"]
|
||||
path = docs
|
||||
url = git@github.com:mattn/go-gtk.git
|
||||
branch = gh-pages
|
1
vendor/github.com/mattn/go-gtk/.test
generated
vendored
Executable file
1
vendor/github.com/mattn/go-gtk/.test
generated
vendored
Executable file
@ -0,0 +1 @@
|
||||
make example
|
28
vendor/github.com/mattn/go-gtk/Makefile
generated
vendored
Normal file
28
vendor/github.com/mattn/go-gtk/Makefile
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
include example/example.mk
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
.PHONY: all
|
||||
all:
|
||||
cd pango && go get -x
|
||||
cd glib && go get -x
|
||||
cd gdk && go get -x
|
||||
cd gdkpixbuf && go get -x
|
||||
cd gtk && go get -x
|
||||
cd gtksourceview && go get -x
|
||||
#cd gtkgl && go get -x .
|
||||
#cd gtkspell && go get -x .
|
||||
|
||||
.PHONY: all
|
||||
fmt:
|
||||
cd pango && go fmt .
|
||||
cd glib && go fmt .
|
||||
cd gdk && go fmt .
|
||||
cd gdkpixbuf && go fmt .
|
||||
cd gtk && go fmt .
|
||||
cd gtksourceview && go fmt .
|
||||
#cd gtkgl && go fmt .
|
||||
#cd gtkspell && go fmt .
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-example
|
||||
@true
|
259
vendor/github.com/mattn/go-gtk/README.md
generated
vendored
Normal file
259
vendor/github.com/mattn/go-gtk/README.md
generated
vendored
Normal file
@ -0,0 +1,259 @@
|
||||
# go-gtk
|
||||
|
||||
## WHATS
|
||||
|
||||
Go bindings for GTK
|
||||
|
||||
## SCREENSHOT
|
||||
|
||||
![Go GTK!](https://github.com/mattn/go-gtk/raw/gh-pages/static/images/screenshot.png "Go GTK!")
|
||||
|
||||
## INSTALL
|
||||
|
||||
You can experiment with go-gtk
|
||||
by running the various example programs:
|
||||
|
||||
git clone https://github.com/mattn/go-gtk
|
||||
cd go-gtk
|
||||
make example
|
||||
./example/demo/demo
|
||||
|
||||
Or
|
||||
|
||||
go get github.com/mattn/go-gtk/gtk
|
||||
|
||||
Don't forget, that you need the GTK-Development-Packages.
|
||||
|
||||
If you use linux, you should install `libgtk+-2.0` and packages that depend on gtk.
|
||||
|
||||
On Debian and Debian derived distributions you can run (as root):
|
||||
|
||||
apt-get install libgtk2.0-dev libglib2.0-dev libgtksourceview2.0-dev
|
||||
|
||||
If you use windows, find gtk binary packages from here:
|
||||
|
||||
* http://www.gtk.org/download/windows.php
|
||||
|
||||
## LICENSE
|
||||
|
||||
The library is available under the same terms and conditions as the Go, the BSD style license, and the LGPL (GNU Lesser General Public License). The idea is that if you can use Go (and Gtk) in a project, you should also be able to use go-gtk.
|
||||
|
||||
## AUTHOR
|
||||
|
||||
* Yasuhiro Matsumoto
|
||||
|
||||
## CONTRIBUTE AUTHORS
|
||||
|
||||
* David Roundy
|
||||
* Mark Andrew Gerads
|
||||
* Tobias Kortkamp
|
||||
* Mikhail Trushnikov
|
||||
* Federico Sogaro
|
||||
* Crazy2be
|
||||
* Daniël de Kok
|
||||
* Erik Lissel
|
||||
* Jeffrey Bolle
|
||||
* Leonhard Küper
|
||||
* Matt Joiner
|
||||
* SQP
|
||||
* Steven T
|
||||
* Taru Karttunen
|
||||
* Utkan Güngördü
|
||||
* matiaslina
|
||||
* Dag Robøle
|
||||
* Denis Dyakov
|
||||
|
||||
## GOAL
|
||||
|
||||
Hopefully support following widgets and methods enough to run general application.
|
||||
|
||||
(output of tools/gogtkinfo)
|
||||
|
||||
Main Loop and Events : 30% ( 8/ 26)
|
||||
GtkAccelGroup : 15% ( 3/ 19)
|
||||
GtkAccelMap : 0% ( 0/ 14)
|
||||
GtkClipboard : 25% ( 8/ 31)
|
||||
Drag and Drop : 11% ( 4/ 35)
|
||||
GtkIconTheme : 0% ( 0/ 31)
|
||||
GtkStockItem : 66% ( 4/ 6)
|
||||
Themeable Stock Images : 0% ( 0/ 41)
|
||||
Resource Files : 14% ( 4/ 28)
|
||||
GtkSettings : 40% ( 6/ 15)
|
||||
GtkBinding : 0% ( 0/ 14)
|
||||
Graphics Contexts : 0% ( 0/ 2)
|
||||
GtkStyle : 9% ( 6/ 64)
|
||||
Selections : 8% ( 4/ 47)
|
||||
Version Information : 0% ( 0/ 6)
|
||||
Testing : 0% ( 0/ 16)
|
||||
Filesystem Utilities : 0% ( 0/ 7)
|
||||
GtkDialog : 45% ( 9/ 20)
|
||||
GtkMessageDialog : 62% ( 5/ 8)
|
||||
GtkWindow : 49% ( 50/102)
|
||||
GtkWindowGroup : 0% ( 0/ 5)
|
||||
GtkAboutDialog : 90% ( 29/ 32)
|
||||
GtkAssistant : 91% ( 21/ 23)
|
||||
GtkOffscreenWindow : 0% ( 0/ 3)
|
||||
GtkAccelLabel : 83% ( 5/ 6)
|
||||
GtkImage : 32% ( 10/ 31)
|
||||
GtkLabel : 86% ( 39/ 45)
|
||||
GtkProgressBar : 100% ( 12/ 12)
|
||||
GtkStatusbar : 77% ( 7/ 9)
|
||||
GtkInfoBar : 100% ( 12/ 12)
|
||||
GtkStatusIcon : 68% ( 26/ 38)
|
||||
GtkSpinner : 100% ( 3/ 3)
|
||||
GtkButton : 100% ( 28/ 28)
|
||||
GtkCheckButton : 100% ( 3/ 3)
|
||||
GtkRadioButton : 100% ( 8/ 8)
|
||||
GtkToggleButton : 100% ( 9/ 9)
|
||||
GtkLinkButton : 75% ( 6/ 8)
|
||||
GtkScaleButton : 100% ( 9/ 9)
|
||||
GtkVolumeButton : 100% ( 1/ 1)
|
||||
GtkEntry : 41% ( 26/ 63)
|
||||
GtkEntryBuffer : 72% ( 8/ 11)
|
||||
GtkEntryCompletion : 96% ( 25/ 26)
|
||||
GtkHScale : 100% ( 2/ 2)
|
||||
GtkVScale : 100% ( 2/ 2)
|
||||
GtkSpinButton : 100% ( 30/ 30)
|
||||
GtkEditable : 100% ( 13/ 13)
|
||||
GtkTextIter : 25% ( 23/ 91)
|
||||
GtkTextMark : 0% ( 0/ 7)
|
||||
GtkTextBuffer : 67% ( 52/ 77)
|
||||
GtkTextTag : 83% ( 5/ 6)
|
||||
GtkTextAttributes : 100% ( 5/ 5)
|
||||
GtkTextTagTable : 83% ( 5/ 6)
|
||||
GtkTextView : 29% ( 19/ 64)
|
||||
GtkTreePath : 90% ( 18/ 20)
|
||||
GtkTreeRowReference : 60% ( 6/ 10)
|
||||
GtkTreeIter : 100% ( 2/ 2)
|
||||
GtkTreeModel : 57% ( 15/ 26)
|
||||
GtkTreeSelection : 78% ( 18/ 23)
|
||||
GtkTreeViewColumn : 61% ( 34/ 55)
|
||||
GtkTreeView : 18% ( 18/ 98)
|
||||
GtkTreeView drag-and-drop : 0% ( 0/ 7)
|
||||
GtkCellView : 0% ( 0/ 11)
|
||||
GtkIconView : 17% ( 11/ 62)
|
||||
GtkTreeSortable : 62% ( 5/ 8)
|
||||
GtkTreeModelSort : 0% ( 0/ 9)
|
||||
GtkTreeModelFilter : 0% ( 0/ 11)
|
||||
GtkCellLayout : 0% ( 0/ 9)
|
||||
GtkCellRenderer : 100% ( 2/ 2)
|
||||
GtkCellEditable : 0% ( 0/ 3)
|
||||
GtkCellRendererAccel : 100% ( 1/ 1)
|
||||
GtkCellRendererCombo : 100% ( 1/ 1)
|
||||
GtkCellRendererPixbuf : 100% ( 1/ 1)
|
||||
GtkCellRendererProgress : 100% ( 1/ 1)
|
||||
GtkCellRendererSpin : 100% ( 1/ 1)
|
||||
GtkCellRendererText : 100% ( 2/ 2)
|
||||
GtkCellRendererToggle : 100% ( 7/ 7)
|
||||
GtkCellRendererSpinner : 100% ( 1/ 1)
|
||||
GtkListStore : 84% ( 16/ 19)
|
||||
GtkTreeStore : 80% ( 17/ 21)
|
||||
GtkComboBox : 78% ( 30/ 38)
|
||||
GtkComboBoxText : 100% ( 7/ 7)
|
||||
GtkComboBoxEntry : 80% ( 4/ 5)
|
||||
GtkMenu : 50% ( 15/ 30)
|
||||
GtkMenuBar : 100% ( 8/ 8)
|
||||
GtkMenuItem : 90% ( 18/ 20)
|
||||
GtkImageMenuItem : 54% ( 6/ 11)
|
||||
GtkRadioMenuItem : 44% ( 4/ 9)
|
||||
GtkCheckMenuItem : 100% ( 10/ 10)
|
||||
GtkSeparatorMenuItem : 100% ( 1/ 1)
|
||||
GtkTearoffMenuItem : 100% ( 1/ 1)
|
||||
GtkToolShell : 0% ( 0/ 9)
|
||||
GtkToolbar : 63% ( 24/ 38)
|
||||
GtkToolItem : 76% ( 19/ 25)
|
||||
GtkToolPalette : 59% ( 13/ 22)
|
||||
GtkToolItemGroup : 47% ( 8/ 17)
|
||||
GtkSeparatorToolItem : 100% ( 3/ 3)
|
||||
GtkToolButton : 100% ( 15/ 15)
|
||||
GtkMenuToolButton : 85% ( 6/ 7)
|
||||
GtkToggleToolButton : 100% ( 5/ 5)
|
||||
GtkRadioToolButton : 33% ( 2/ 6)
|
||||
GtkUIManager : 29% ( 5/ 17)
|
||||
GtkActionGroup : 55% ( 11/ 20)
|
||||
GtkAction : 93% ( 44/ 47)
|
||||
GtkToggleAction : 100% ( 6/ 6)
|
||||
GtkRadioAction : 100% ( 5/ 5)
|
||||
GtkRecentAction : 75% ( 3/ 4)
|
||||
GtkActivatable : 66% ( 4/ 6)
|
||||
GtkColorButton : 100% ( 10/ 10)
|
||||
GtkColorSelectionDialog : 0% ( 0/ 2)
|
||||
GtkColorSelection : 0% ( 0/ 21)
|
||||
GtkHSV : 0% ( 0/ 8)
|
||||
GtkFileChooser : 22% ( 13/ 58)
|
||||
GtkFileChooserButton : 18% ( 2/ 11)
|
||||
GtkFileChooserDialog : 100% ( 1/ 1)
|
||||
GtkFileChooserWidget : 50% ( 1/ 2)
|
||||
GtkFileFilter : 55% ( 5/ 9)
|
||||
GtkFontButton : 100% ( 14/ 14)
|
||||
GtkFontSelection : 28% ( 4/ 14)
|
||||
GtkFontSelectionDialog : 100% ( 8/ 8)
|
||||
GtkInputDialog : 0% ( 0/ 1)
|
||||
GtkAlignment : 100% ( 4/ 4)
|
||||
GtkAspectFrame : 0% ( 0/ 2)
|
||||
GtkHBox : 100% ( 1/ 1)
|
||||
GtkVBox : 100% ( 1/ 1)
|
||||
GtkHButtonBox : 0% ( 0/ 5)
|
||||
GtkVButtonBox : 0% ( 0/ 5)
|
||||
GtkFixed : 100% ( 5/ 5)
|
||||
GtkHPaned : 100% ( 1/ 1)
|
||||
GtkVPaned : 100% ( 1/ 1)
|
||||
GtkLayout : 100% ( 12/ 12)
|
||||
GtkNotebook : 90% ( 50/ 55)
|
||||
GtkTable : 93% ( 14/ 15)
|
||||
GtkExpander : 87% ( 14/ 16)
|
||||
GtkOrientable : 0% ( 0/ 2)
|
||||
GtkFrame : 100% ( 9/ 9)
|
||||
GtkHSeparator : 100% ( 1/ 1)
|
||||
GtkVSeparator : 100% ( 1/ 1)
|
||||
GtkScrollbar : 100% ( 0/ 0)
|
||||
GtkHScrollbar : 100% ( 1/ 1)
|
||||
GtkVScrollbar : 100% ( 1/ 1)
|
||||
GtkScrolledWindow : 86% ( 13/ 15)
|
||||
GtkPrintOperation : 13% ( 5/ 36)
|
||||
GtkPrintContext : 18% ( 2/ 11)
|
||||
GtkPrintSettings : 0% ( 0/ 74)
|
||||
GtkPageSetup : 0% ( 0/ 25)
|
||||
GtkPaperSize : 0% ( 0/ 21)
|
||||
GtkPrinter : 0% ( 0/ 23)
|
||||
GtkPrintJob : 0% ( 0/ 10)
|
||||
GtkPrintUnixDialog : 0% ( 0/ 18)
|
||||
GtkPageSetupUnixDialog : 0% ( 0/ 5)
|
||||
GtkAdjustment : 83% ( 15/ 18)
|
||||
GtkArrow : 100% ( 2/ 2)
|
||||
GtkCalendar : 0% ( 0/ 17)
|
||||
GtkDrawingArea : 100% ( 2/ 2)
|
||||
GtkEventBox : 20% ( 1/ 5)
|
||||
GtkHandleBox : 0% ( 0/ 8)
|
||||
GtkIMContextSimple : 0% ( 0/ 2)
|
||||
GtkIMMulticontext : 0% ( 0/ 4)
|
||||
GtkSizeGroup : 100% ( 8/ 8)
|
||||
GtkTooltip : 60% ( 6/ 10)
|
||||
GtkViewport : 100% ( 9/ 9)
|
||||
GtkAccessible : 100% ( 3/ 3)
|
||||
GtkBin : 100% ( 1/ 1)
|
||||
GtkBox : 100% ( 11/ 11)
|
||||
GtkButtonBox : 0% ( 0/ 10)
|
||||
GtkContainer : 48% ( 16/ 33)
|
||||
GtkItem : 100% ( 3/ 3)
|
||||
GtkMenuShell : 0% ( 0/ 11)
|
||||
GtkMisc : 100% ( 4/ 4)
|
||||
GtkObject : 100% ( 2/ 2)
|
||||
GtkPaned : 88% ( 8/ 9)
|
||||
GtkRange : 53% ( 16/ 30)
|
||||
GtkScale : 90% ( 9/ 10)
|
||||
GtkSeparator : 100% ( 0/ 0)
|
||||
GtkWidget : 54% (101/187)
|
||||
GtkIMContext : 0% ( 0/ 11)
|
||||
GtkPlug : 0% ( 0/ 7)
|
||||
GtkSocket : 0% ( 0/ 5)
|
||||
GtkRecentManager : 0% ( 0/ 37)
|
||||
GtkRecentChooser : 0% ( 0/ 33)
|
||||
GtkRecentChooserDialog : 0% ( 0/ 2)
|
||||
GtkRecentChooserMenu : 0% ( 0/ 4)
|
||||
GtkRecentChooserWidget : 0% ( 0/ 2)
|
||||
GtkRecentFilter : 0% ( 0/ 12)
|
||||
GtkBuildable : 0% ( 0/ 10)
|
||||
|
||||
Total progress : 47% (1519/3180)
|
||||
|
4
vendor/github.com/mattn/go-gtk/TODO
generated
vendored
Normal file
4
vendor/github.com/mattn/go-gtk/TODO
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
* more widgets.
|
||||
* main loop handling (using goroutine) (done)
|
||||
* split gtksourceview from gtk package (done)
|
||||
* copyright header in sources
|
BIN
vendor/github.com/mattn/go-gtk/data/go-gtk-logo.png
generated
vendored
Normal file
BIN
vendor/github.com/mattn/go-gtk/data/go-gtk-logo.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
vendor/github.com/mattn/go-gtk/data/mattn-logo.png
generated
vendored
Normal file
BIN
vendor/github.com/mattn/go-gtk/data/mattn-logo.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
vendor/github.com/mattn/go-gtk/data/win32-demo.png
generated
vendored
Normal file
BIN
vendor/github.com/mattn/go-gtk/data/win32-demo.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
vendor/github.com/mattn/go-gtk/data/win32-twitter.png
generated
vendored
Normal file
BIN
vendor/github.com/mattn/go-gtk/data/win32-twitter.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
222
vendor/github.com/mattn/go-gtk/example/action/action.go
generated
vendored
Normal file
222
vendor/github.com/mattn/go-gtk/example/action/action.go
generated
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func CreateWindow() *gtk.Window {
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetDefaultSize(700, 300)
|
||||
vbox := gtk.NewVBox(false, 1)
|
||||
CreateMenuAndToolbar(window, vbox)
|
||||
CreateActivatableDemo(vbox)
|
||||
window.Add(vbox)
|
||||
return window
|
||||
}
|
||||
|
||||
func CreateMenuAndToolbar(w *gtk.Window, vbox *gtk.VBox) {
|
||||
action_group := gtk.NewActionGroup("my_group")
|
||||
ui_manager := CreateUIManager()
|
||||
accel_group := ui_manager.GetAccelGroup()
|
||||
w.AddAccelGroup(accel_group)
|
||||
AddFileMenuActions(action_group)
|
||||
AddEditMenuActions(action_group)
|
||||
AddChoicesMenuActions(action_group)
|
||||
ui_manager.InsertActionGroup(action_group, 0)
|
||||
menubar := ui_manager.GetWidget("/MenuBar")
|
||||
vbox.PackStart(menubar, false, false, 0)
|
||||
toolbar := ui_manager.GetWidget("/ToolBar")
|
||||
vbox.PackStart(toolbar, false, false, 0)
|
||||
eventbox := gtk.NewEventBox()
|
||||
vbox.PackStart(eventbox, false, false, 0)
|
||||
// label := gtk.NewLabel("Right-click to see the popup menu.")
|
||||
// vbox.PackStart(label, false, false, 0)
|
||||
}
|
||||
|
||||
func CreateActivatableDemo(vbox *gtk.VBox) {
|
||||
action_entry := gtk.NewAction("ActionEntry",
|
||||
"Button attached to Action", "", gtk.STOCK_INFO)
|
||||
action_entry.Connect("activate", func() {
|
||||
fmt.Println("Action clicked")
|
||||
})
|
||||
frame1 := gtk.NewFrame("GtkActivatable interface demonstration")
|
||||
frame1.SetBorderWidth(5)
|
||||
hbox2 := gtk.NewHBox(false, 5)
|
||||
hbox2.SetSizeRequest(400, 50)
|
||||
hbox2.SetBorderWidth(5)
|
||||
button1 := gtk.NewButton()
|
||||
button1.SetSizeRequest(250, 0)
|
||||
button1.SetRelatedAction(action_entry)
|
||||
hbox2.PackStart(button1, false, false, 0)
|
||||
hbox2.PackStart(gtk.NewVSeparator(), false, false, 0)
|
||||
button2 := gtk.NewButtonWithLabel("Hide Action")
|
||||
button2.SetSizeRequest(150, 0)
|
||||
button2.Connect("clicked", func() {
|
||||
action_entry.SetVisible(false)
|
||||
fmt.Println("Hide Action")
|
||||
})
|
||||
hbox2.PackStart(button2, false, false, 0)
|
||||
button3 := gtk.NewButtonWithLabel("Unhide Action")
|
||||
button3.SetSizeRequest(150, 0)
|
||||
button3.Connect("clicked", func() {
|
||||
action_entry.SetVisible(true)
|
||||
fmt.Println("Show Action")
|
||||
})
|
||||
hbox2.PackStart(button3, false, false, 0)
|
||||
frame1.Add(hbox2)
|
||||
vbox.PackStart(frame1, false, true, 0)
|
||||
}
|
||||
|
||||
func CreateUIManager() *gtk.UIManager {
|
||||
UI_INFO := `
|
||||
<ui>
|
||||
<menubar name='MenuBar'>
|
||||
<menu action='FileMenu'>
|
||||
<menu action='FileNew'>
|
||||
<menuitem action='FileNewStandard' />
|
||||
<menuitem action='FileNewFoo' />
|
||||
<menuitem action='FileNewGoo' />
|
||||
</menu>
|
||||
<separator />
|
||||
<menuitem action='FileQuit' />
|
||||
</menu>
|
||||
<menu action='EditMenu'>
|
||||
<menuitem action='EditCopy' />
|
||||
<menuitem action='EditPaste' />
|
||||
<menuitem action='EditSomething' />
|
||||
</menu>
|
||||
<menu action='ChoicesMenu'>
|
||||
<menuitem action='ChoiceOne'/>
|
||||
<menuitem action='ChoiceTwo'/>
|
||||
<menuitem action='ChoiceThree'/>
|
||||
<separator />
|
||||
<menuitem action='ChoiceToggle'/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name='ToolBar'>
|
||||
<toolitem action='FileNewStandard' />
|
||||
<toolitem action='FileQuit' />
|
||||
</toolbar>
|
||||
<popup name='PopupMenu'>
|
||||
<menuitem action='EditCopy' />
|
||||
<menuitem action='EditPaste' />
|
||||
<menuitem action='EditSomething' />
|
||||
</popup>
|
||||
</ui>
|
||||
`
|
||||
ui_manager := gtk.NewUIManager()
|
||||
ui_manager.AddUIFromString(UI_INFO)
|
||||
return ui_manager
|
||||
}
|
||||
|
||||
func OnMenuFileNewGeneric() {
|
||||
fmt.Println("A File|New menu item was selected.")
|
||||
}
|
||||
|
||||
func OnMenuFileQuit() {
|
||||
fmt.Println("quit app...")
|
||||
gtk.MainQuit()
|
||||
}
|
||||
|
||||
func OnMenuOther(ctx *glib.CallbackContext) {
|
||||
v := reflect.ValueOf(ctx.Target())
|
||||
if v.Kind() == reflect.Ptr {
|
||||
fmt.Printf("Item %s(%p) was selected", v.Elem(), v.Interface())
|
||||
fmt.Println()
|
||||
if w, ok := v.Elem().Interface().(gtk.IWidget); ok {
|
||||
v := reflect.ValueOf(ctx.Target())
|
||||
v2 := v.Elem()
|
||||
fmt.Println(v.Kind(), v2.Kind())
|
||||
fmt.Println("Menu item ", w.GetName(), " was selected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func OnMenuOther2(widget unsafe.Pointer, event unsafe.Pointer,
|
||||
data unsafe.Pointer) {
|
||||
fmt.Println("Menu item ", "", " was selected")
|
||||
}
|
||||
|
||||
func AddFileMenuActions(action_group *gtk.ActionGroup) {
|
||||
action_group.AddAction(gtk.NewAction("FileMenu", "File", "", ""))
|
||||
|
||||
action_filenewmenu := gtk.NewAction("FileNew", "", "", gtk.STOCK_NEW)
|
||||
action_group.AddAction(action_filenewmenu)
|
||||
|
||||
action_new := gtk.NewAction("FileNewStandard", "_New",
|
||||
"Create a new file", gtk.STOCK_NEW)
|
||||
action_new.Connect("activate", OnMenuFileNewGeneric)
|
||||
action_group.AddActionWithAccel(action_new, "")
|
||||
|
||||
action_new_foo := gtk.NewAction("FileNewFoo", "New Foo",
|
||||
"Create new foo", gtk.STOCK_NEW)
|
||||
action_new_foo.Connect("activate", OnMenuFileNewGeneric)
|
||||
action_group.AddAction(action_new_foo)
|
||||
|
||||
action_new_goo := gtk.NewAction("FileNewGoo", "_New Goo",
|
||||
"Create new goo", gtk.STOCK_NEW)
|
||||
action_new_goo.Connect("activate", OnMenuFileNewGeneric)
|
||||
action_group.AddAction(action_new_goo)
|
||||
|
||||
action_filequit := gtk.NewAction("FileQuit", "", "", gtk.STOCK_QUIT)
|
||||
action_filequit.Connect("activate", OnMenuFileQuit)
|
||||
action_group.AddActionWithAccel(action_filequit, "")
|
||||
}
|
||||
|
||||
func AddEditMenuActions(action_group *gtk.ActionGroup) {
|
||||
action_group.AddAction(gtk.NewAction("EditMenu", "Edit", "", ""))
|
||||
|
||||
action_editcopy := gtk.NewAction("EditCopy", "", "", gtk.STOCK_COPY)
|
||||
action_editcopy.Connect("activate", OnMenuOther)
|
||||
action_group.AddActionWithAccel(action_editcopy, "")
|
||||
|
||||
action_editpaste := gtk.NewAction("EditPaste", "", "", gtk.STOCK_PASTE)
|
||||
action_editpaste.Connect("activate", OnMenuOther)
|
||||
action_group.AddActionWithAccel(action_editpaste, "")
|
||||
|
||||
action_editsomething := gtk.NewAction("EditSomething", "Something", "", "")
|
||||
action_editsomething.Connect("activate", OnMenuOther)
|
||||
action_group.AddActionWithAccel(action_editsomething, "<control><alt>S")
|
||||
}
|
||||
|
||||
func AddChoicesMenuActions(action_group *gtk.ActionGroup) {
|
||||
action_group.AddAction(gtk.NewAction("ChoicesMenu", "Choices", "", ""))
|
||||
|
||||
var ra_list []*gtk.RadioAction
|
||||
ra_one := gtk.NewRadioAction("ChoiceOne", "One", "", "", 1)
|
||||
ra_list = append(ra_list, ra_one)
|
||||
|
||||
ra_two := gtk.NewRadioAction("ChoiceTwo", "Two", "", "", 2)
|
||||
ra_list = append(ra_list, ra_two)
|
||||
|
||||
ra_three := gtk.NewRadioAction("ChoiceThree", "Three", "", "", 2)
|
||||
ra_list = append(ra_list, ra_three)
|
||||
|
||||
var sl *glib.SList
|
||||
for _, ra := range ra_list {
|
||||
ra.SetGroup(sl)
|
||||
sl = ra.GetGroup()
|
||||
action_group.AddAction(ra)
|
||||
}
|
||||
|
||||
ra_last := gtk.NewToggleAction("ChoiceToggle", "Toggle", "", "")
|
||||
ra_last.SetActive(true)
|
||||
action_group.AddAction(ra_last)
|
||||
}
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
window := CreateWindow()
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
fmt.Println("destroy pending...")
|
||||
gtk.MainQuit()
|
||||
}, "foo")
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
43
vendor/github.com/mattn/go-gtk/example/alignment/alignment.go
generated
vendored
Normal file
43
vendor/github.com/mattn/go-gtk/example/alignment/alignment.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("Alignment")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
notebook := gtk.NewNotebook()
|
||||
window.Add(notebook)
|
||||
|
||||
align := gtk.NewAlignment(0.5, 0.5, 0.5, 0.5)
|
||||
notebook.AppendPage(align, gtk.NewLabel("Alignment"))
|
||||
|
||||
button := gtk.NewButtonWithLabel("Hello World!")
|
||||
align.Add(button)
|
||||
|
||||
fixed := gtk.NewFixed()
|
||||
notebook.AppendPage(fixed, gtk.NewLabel("Fixed"))
|
||||
|
||||
button2 := gtk.NewButtonWithLabel("Pulse")
|
||||
fixed.Put(button2, 30, 30)
|
||||
|
||||
progress := gtk.NewProgressBar()
|
||||
fixed.Put(progress, 30, 70)
|
||||
|
||||
button.Connect("clicked", func() {
|
||||
progress.SetFraction(0.1 + 0.9*progress.GetFraction()) //easter egg
|
||||
})
|
||||
button2.Connect("clicked", func() {
|
||||
progress.Pulse()
|
||||
})
|
||||
|
||||
window.ShowAll()
|
||||
window.SetSizeRequest(200, 200)
|
||||
|
||||
gtk.Main()
|
||||
}
|
48
vendor/github.com/mattn/go-gtk/example/arrow/arrow.go
generated
vendored
Normal file
48
vendor/github.com/mattn/go-gtk/example/arrow/arrow.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
)
|
||||
|
||||
func createArrowButton(at gtk.ArrowType, st gtk.ShadowType) *gtk.Button {
|
||||
b := gtk.NewButton()
|
||||
a := gtk.NewArrow(at, st)
|
||||
|
||||
b.Add(a)
|
||||
|
||||
b.Show()
|
||||
a.Show()
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("Arrow Buttons")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
box := gtk.NewHBox(false, 0)
|
||||
box.Show()
|
||||
window.Add(box)
|
||||
|
||||
up := createArrowButton(gtk.ARROW_UP, gtk.SHADOW_IN)
|
||||
down := createArrowButton(gtk.ARROW_DOWN, gtk.SHADOW_OUT)
|
||||
left := createArrowButton(gtk.ARROW_LEFT, gtk.SHADOW_ETCHED_IN)
|
||||
right := createArrowButton(gtk.ARROW_RIGHT, gtk.SHADOW_ETCHED_OUT)
|
||||
|
||||
box.PackStart(up, false, false, 3)
|
||||
box.PackStart(down, false, false, 3)
|
||||
box.PackStart(left, false, false, 3)
|
||||
box.PackStart(right, false, false, 3)
|
||||
|
||||
up.Clicked(func() { println("↑") })
|
||||
down.Clicked(func() { println("↓") })
|
||||
left.Clicked(func() { println("←") })
|
||||
right.Clicked(func() { println("→") })
|
||||
|
||||
window.Show()
|
||||
gtk.Main()
|
||||
}
|
26
vendor/github.com/mattn/go-gtk/example/builder/builder.go
generated
vendored
Normal file
26
vendor/github.com/mattn/go-gtk/example/builder/builder.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-gtk/example/builder/callback"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
//"github.com/mattn/go-gtk/example/builder/callback"
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
|
||||
builder := gtk.NewBuilder()
|
||||
|
||||
builder.AddFromFile("hello.ui")
|
||||
obj := builder.GetObject("window1")
|
||||
|
||||
window := gtk.WidgetFromObject(obj)
|
||||
window.Show()
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
callback.Init(builder)
|
||||
|
||||
gtk.Main()
|
||||
}
|
37
vendor/github.com/mattn/go-gtk/example/builder/callback/callback.go
generated
vendored
Normal file
37
vendor/github.com/mattn/go-gtk/example/builder/callback/callback.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package callback
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
var aboutdialog *gtk.AboutDialog
|
||||
|
||||
func Init(builder *gtk.Builder) {
|
||||
aboutdialog = >k.AboutDialog{
|
||||
*(*gtk.Dialog)(unsafe.Pointer(&builder.GetObject("aboutdialog1").Object))}
|
||||
builder.ConnectSignalsFull(func(builder *gtk.Builder, obj *glib.GObject, sig, handler string, conn *glib.GObject, flags glib.ConnectFlags, user_data interface{}) {
|
||||
switch handler {
|
||||
case "on_imagemenuitem1_activate":
|
||||
obj.SignalConnect(sig, on_imagemenuitem1_activate, user_data, flags)
|
||||
case "on_show_aboutdialog_activate":
|
||||
obj.SignalConnect(sig, on_show_aboutdialog_activate, user_data, flags)
|
||||
case "gtk_widget_hide":
|
||||
obj.SignalConnect(sig, func(c *glib.CallbackContext) {
|
||||
gtk.WidgetFromObject(c.Target().(*glib.GObject)).Hide()
|
||||
}, nil, flags)
|
||||
}
|
||||
}, nil)
|
||||
}
|
||||
|
||||
//export on_imagemenuitem1_activate
|
||||
func on_imagemenuitem1_activate() {
|
||||
gtk.MainQuit()
|
||||
}
|
||||
|
||||
//export on_show_aboutdialog_activate
|
||||
func on_show_aboutdialog_activate() {
|
||||
aboutdialog.Run()
|
||||
}
|
139
vendor/github.com/mattn/go-gtk/example/builder/hello.ui
generated
vendored
Normal file
139
vendor/github.com/mattn/go-gtk/example/builder/hello.ui
generated
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="program_name">go-gtk builder</property>
|
||||
<property name="version">0.1</property>
|
||||
<property name="copyright">The library is available under the same terms and conditions as the Go,
|
||||
the BSD style license, and the LGPL (Lesser GNU Public License).
|
||||
The idea is that if you can use Go (and Gtk) in a project, you should also be able to use go-gtk.</property>
|
||||
<property name="comments" translatable="yes">example program for go-gtk</property>
|
||||
<property name="website">https://github.com/mattn/go-gtk</property>
|
||||
<property name="authors">Yasuhiro Matsumoto</property>
|
||||
<signal name="response" handler="gtk_widget_hide" swapped="no"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixbuf">../../data/mattn-logo.png</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">builder</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuBar" id="menubar1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="file">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="exit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="do_exit">
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_imagemenuitem1_activate" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="help">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="right_justified">True</property>
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="about">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="show_aboutdialog">
|
||||
<property name="label">gtk-about</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_show_aboutdialog_activate" after="yes" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLinkButton" id="linkbutton1">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="tooltip_markup"><b>http://mattn.kaoriya.net/</b></property>
|
||||
<property name="image">image1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="uri">http://mattn.kaoriya.net/</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
19
vendor/github.com/mattn/go-gtk/example/clipboard/clipboard.go
generated
vendored
Normal file
19
vendor/github.com/mattn/go-gtk/example/clipboard/clipboard.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
clipboard := gtk.NewClipboardGetForDisplay(
|
||||
gdk.DisplayGetDefault(),
|
||||
gdk.SELECTION_CLIPBOARD)
|
||||
fmt.Println(clipboard.WaitForText())
|
||||
clipboard.SetText("helloworld")
|
||||
gtk.MainIterationDo(true)
|
||||
clipboard.Store()
|
||||
gtk.MainIterationDo(true)
|
||||
}
|
355
vendor/github.com/mattn/go-gtk/example/demo/demo.go
generated
vendored
Normal file
355
vendor/github.com/mattn/go-gtk/example/demo/demo.go
generated
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func uniq(strings []string) (ret []string) {
|
||||
return
|
||||
}
|
||||
|
||||
func authors() []string {
|
||||
if b, err := exec.Command("git", "log").Output(); err == nil {
|
||||
lines := strings.Split(string(b), "\n")
|
||||
|
||||
var a []string
|
||||
r := regexp.MustCompile(`^Author:\s*([^ <]+).*$`)
|
||||
for _, e := range lines {
|
||||
ms := r.FindStringSubmatch(e)
|
||||
if ms == nil {
|
||||
continue
|
||||
}
|
||||
a = append(a, ms[1])
|
||||
}
|
||||
sort.Strings(a)
|
||||
var p string
|
||||
lines = []string{}
|
||||
for _, e := range a {
|
||||
if p == e {
|
||||
continue
|
||||
}
|
||||
lines = append(lines, e)
|
||||
p = e
|
||||
}
|
||||
return lines
|
||||
}
|
||||
return []string{"Yasuhiro Matsumoto <mattn.jp@gmail.com>"}
|
||||
}
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("GTK Go!")
|
||||
window.SetIconName("gtk-dialog-info")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
fmt.Println("got destroy!", ctx.Data().(string))
|
||||
gtk.MainQuit()
|
||||
}, "foo")
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkVBox
|
||||
//--------------------------------------------------------
|
||||
vbox := gtk.NewVBox(false, 1)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkMenuBar
|
||||
//--------------------------------------------------------
|
||||
menubar := gtk.NewMenuBar()
|
||||
vbox.PackStart(menubar, false, false, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkVPaned
|
||||
//--------------------------------------------------------
|
||||
vpaned := gtk.NewVPaned()
|
||||
vbox.Add(vpaned)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkFrame
|
||||
//--------------------------------------------------------
|
||||
frame1 := gtk.NewFrame("Demo")
|
||||
framebox1 := gtk.NewVBox(false, 1)
|
||||
frame1.Add(framebox1)
|
||||
|
||||
frame2 := gtk.NewFrame("Demo")
|
||||
framebox2 := gtk.NewVBox(false, 1)
|
||||
frame2.Add(framebox2)
|
||||
|
||||
vpaned.Pack1(frame1, false, false)
|
||||
vpaned.Pack2(frame2, false, false)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkImage
|
||||
//--------------------------------------------------------
|
||||
dir, _ := filepath.Split(os.Args[0])
|
||||
imagefile := filepath.Join(dir, "../../data/go-gtk-logo.png")
|
||||
|
||||
label := gtk.NewLabel("Go Binding for GTK")
|
||||
label.ModifyFontEasy("DejaVu Serif 15")
|
||||
framebox1.PackStart(label, false, true, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkEntry
|
||||
//--------------------------------------------------------
|
||||
entry := gtk.NewEntry()
|
||||
entry.SetText("Hello world")
|
||||
framebox1.Add(entry)
|
||||
|
||||
image := gtk.NewImageFromFile(imagefile)
|
||||
framebox1.Add(image)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkScale
|
||||
//--------------------------------------------------------
|
||||
scale := gtk.NewHScaleWithRange(0, 100, 1)
|
||||
scale.Connect("value-changed", func() {
|
||||
fmt.Println("scale:", int(scale.GetValue()))
|
||||
})
|
||||
framebox2.Add(scale)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkHBox
|
||||
//--------------------------------------------------------
|
||||
buttons := gtk.NewHBox(false, 1)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkButton
|
||||
//--------------------------------------------------------
|
||||
button := gtk.NewButtonWithLabel("Button with label")
|
||||
button.Clicked(func() {
|
||||
fmt.Println("button clicked:", button.GetLabel())
|
||||
messagedialog := gtk.NewMessageDialog(
|
||||
button.GetTopLevelAsWindow(),
|
||||
gtk.DIALOG_MODAL,
|
||||
gtk.MESSAGE_INFO,
|
||||
gtk.BUTTONS_OK,
|
||||
entry.GetText())
|
||||
messagedialog.Response(func() {
|
||||
fmt.Println("Dialog OK!")
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkFileChooserDialog
|
||||
//--------------------------------------------------------
|
||||
filechooserdialog := gtk.NewFileChooserDialog(
|
||||
"Choose File...",
|
||||
button.GetTopLevelAsWindow(),
|
||||
gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
gtk.STOCK_OK,
|
||||
gtk.RESPONSE_ACCEPT)
|
||||
filter := gtk.NewFileFilter()
|
||||
filter.AddPattern("*.go")
|
||||
filechooserdialog.AddFilter(filter)
|
||||
filechooserdialog.Response(func() {
|
||||
fmt.Println(filechooserdialog.GetFilename())
|
||||
filechooserdialog.Destroy()
|
||||
})
|
||||
filechooserdialog.Run()
|
||||
messagedialog.Destroy()
|
||||
})
|
||||
messagedialog.Run()
|
||||
})
|
||||
buttons.Add(button)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkFontButton
|
||||
//--------------------------------------------------------
|
||||
fontbutton := gtk.NewFontButton()
|
||||
fontbutton.Connect("font-set", func() {
|
||||
fmt.Println("title:", fontbutton.GetTitle())
|
||||
fmt.Println("fontname:", fontbutton.GetFontName())
|
||||
fmt.Println("use_size:", fontbutton.GetUseSize())
|
||||
fmt.Println("show_size:", fontbutton.GetShowSize())
|
||||
})
|
||||
buttons.Add(fontbutton)
|
||||
framebox2.PackStart(buttons, false, false, 0)
|
||||
|
||||
buttons = gtk.NewHBox(false, 1)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkToggleButton
|
||||
//--------------------------------------------------------
|
||||
togglebutton := gtk.NewToggleButtonWithLabel("ToggleButton with label")
|
||||
togglebutton.Connect("toggled", func() {
|
||||
if togglebutton.GetActive() {
|
||||
togglebutton.SetLabel("ToggleButton ON!")
|
||||
} else {
|
||||
togglebutton.SetLabel("ToggleButton OFF!")
|
||||
}
|
||||
})
|
||||
buttons.Add(togglebutton)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkCheckButton
|
||||
//--------------------------------------------------------
|
||||
checkbutton := gtk.NewCheckButtonWithLabel("CheckButton with label")
|
||||
checkbutton.Connect("toggled", func() {
|
||||
if checkbutton.GetActive() {
|
||||
checkbutton.SetLabel("CheckButton CHECKED!")
|
||||
} else {
|
||||
checkbutton.SetLabel("CheckButton UNCHECKED!")
|
||||
}
|
||||
})
|
||||
buttons.Add(checkbutton)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkRadioButton
|
||||
//--------------------------------------------------------
|
||||
buttonbox := gtk.NewVBox(false, 1)
|
||||
radiofirst := gtk.NewRadioButtonWithLabel(nil, "Radio1")
|
||||
buttonbox.Add(radiofirst)
|
||||
buttonbox.Add(gtk.NewRadioButtonWithLabel(radiofirst.GetGroup(), "Radio2"))
|
||||
buttonbox.Add(gtk.NewRadioButtonWithLabel(radiofirst.GetGroup(), "Radio3"))
|
||||
buttons.Add(buttonbox)
|
||||
//radiobutton.SetMode(false);
|
||||
radiofirst.SetActive(true)
|
||||
|
||||
framebox2.PackStart(buttons, false, false, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkVSeparator
|
||||
//--------------------------------------------------------
|
||||
vsep := gtk.NewVSeparator()
|
||||
framebox2.PackStart(vsep, false, false, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkComboBoxEntry
|
||||
//--------------------------------------------------------
|
||||
combos := gtk.NewHBox(false, 1)
|
||||
comboboxentry := gtk.NewComboBoxText()
|
||||
comboboxentry.AppendText("Monkey")
|
||||
comboboxentry.AppendText("Tiger")
|
||||
comboboxentry.AppendText("Elephant")
|
||||
comboboxentry.Connect("changed", func() {
|
||||
fmt.Println("value:", comboboxentry.GetActiveText())
|
||||
})
|
||||
combos.Add(comboboxentry)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkComboBox
|
||||
//--------------------------------------------------------
|
||||
combobox := gtk.NewComboBoxText()
|
||||
combobox.AppendText("Peach")
|
||||
combobox.AppendText("Banana")
|
||||
combobox.AppendText("Apple")
|
||||
combobox.SetActive(1)
|
||||
combobox.Connect("changed", func() {
|
||||
fmt.Println("value:", combobox.GetActiveText())
|
||||
})
|
||||
combos.Add(combobox)
|
||||
|
||||
framebox2.PackStart(combos, false, false, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkTextView
|
||||
//--------------------------------------------------------
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
swin.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
swin.SetShadowType(gtk.SHADOW_IN)
|
||||
textview := gtk.NewTextView()
|
||||
var start, end gtk.TextIter
|
||||
buffer := textview.GetBuffer()
|
||||
buffer.GetStartIter(&start)
|
||||
buffer.Insert(&start, "Hello ")
|
||||
buffer.GetEndIter(&end)
|
||||
buffer.Insert(&end, "World!")
|
||||
tag := buffer.CreateTag("bold", map[string]string{
|
||||
"background": "#FF0000", "weight": "700"})
|
||||
buffer.GetStartIter(&start)
|
||||
buffer.GetEndIter(&end)
|
||||
buffer.ApplyTag(tag, &start, &end)
|
||||
swin.Add(textview)
|
||||
framebox2.Add(swin)
|
||||
|
||||
buffer.Connect("changed", func() {
|
||||
fmt.Println("changed")
|
||||
})
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkMenuItem
|
||||
//--------------------------------------------------------
|
||||
cascademenu := gtk.NewMenuItemWithMnemonic("_File")
|
||||
menubar.Append(cascademenu)
|
||||
submenu := gtk.NewMenu()
|
||||
cascademenu.SetSubmenu(submenu)
|
||||
|
||||
var menuitem *gtk.MenuItem
|
||||
menuitem = gtk.NewMenuItemWithMnemonic("E_xit")
|
||||
menuitem.Connect("activate", func() {
|
||||
gtk.MainQuit()
|
||||
})
|
||||
submenu.Append(menuitem)
|
||||
|
||||
cascademenu = gtk.NewMenuItemWithMnemonic("_View")
|
||||
menubar.Append(cascademenu)
|
||||
submenu = gtk.NewMenu()
|
||||
cascademenu.SetSubmenu(submenu)
|
||||
|
||||
checkmenuitem := gtk.NewCheckMenuItemWithMnemonic("_Disable")
|
||||
checkmenuitem.Connect("activate", func() {
|
||||
vpaned.SetSensitive(!checkmenuitem.GetActive())
|
||||
})
|
||||
submenu.Append(checkmenuitem)
|
||||
|
||||
menuitem = gtk.NewMenuItemWithMnemonic("_Font")
|
||||
menuitem.Connect("activate", func() {
|
||||
fsd := gtk.NewFontSelectionDialog("Font")
|
||||
fsd.SetFontName(fontbutton.GetFontName())
|
||||
fsd.Response(func() {
|
||||
fmt.Println(fsd.GetFontName())
|
||||
fontbutton.SetFontName(fsd.GetFontName())
|
||||
fsd.Destroy()
|
||||
})
|
||||
fsd.SetTransientFor(window)
|
||||
fsd.Run()
|
||||
})
|
||||
submenu.Append(menuitem)
|
||||
|
||||
cascademenu = gtk.NewMenuItemWithMnemonic("_Help")
|
||||
menubar.Append(cascademenu)
|
||||
submenu = gtk.NewMenu()
|
||||
cascademenu.SetSubmenu(submenu)
|
||||
|
||||
menuitem = gtk.NewMenuItemWithMnemonic("_About")
|
||||
menuitem.Connect("activate", func() {
|
||||
dialog := gtk.NewAboutDialog()
|
||||
dialog.SetName("Go-Gtk Demo!")
|
||||
dialog.SetProgramName("demo")
|
||||
dialog.SetAuthors(authors())
|
||||
dir, _ := filepath.Split(os.Args[0])
|
||||
imagefile := filepath.Join(dir, "../../data/mattn-logo.png")
|
||||
pixbuf, _ := gdkpixbuf.NewPixbufFromFile(imagefile)
|
||||
dialog.SetLogo(pixbuf)
|
||||
dialog.SetLicense("The library is available under the same terms and conditions as the Go, the BSD style license, and the LGPL (Lesser GNU Public License). The idea is that if you can use Go (and Gtk) in a project, you should also be able to use go-gtk.")
|
||||
dialog.SetWrapLicense(true)
|
||||
dialog.Run()
|
||||
dialog.Destroy()
|
||||
})
|
||||
submenu.Append(menuitem)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkStatusbar
|
||||
//--------------------------------------------------------
|
||||
statusbar := gtk.NewStatusbar()
|
||||
context_id := statusbar.GetContextId("go-gtk")
|
||||
statusbar.Push(context_id, "GTK binding for Go!")
|
||||
|
||||
framebox2.PackStart(statusbar, false, false, 0)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Event
|
||||
//--------------------------------------------------------
|
||||
window.Add(vbox)
|
||||
window.SetSizeRequest(600, 600)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
64
vendor/github.com/mattn/go-gtk/example/dnd/dnd.go
generated
vendored
Normal file
64
vendor/github.com/mattn/go-gtk/example/dnd/dnd.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK DND")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
vbox := gtk.NewVBox(true, 0)
|
||||
vbox.SetBorderWidth(5)
|
||||
|
||||
targets := []gtk.TargetEntry{
|
||||
{"text/uri-list", 0, 0},
|
||||
{"STRING", 0, 1},
|
||||
{"text/plain", 0, 2},
|
||||
}
|
||||
dest := gtk.NewLabel("drop me file")
|
||||
dest.DragDestSet(
|
||||
gtk.DEST_DEFAULT_MOTION|
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT|
|
||||
gtk.DEST_DEFAULT_DROP,
|
||||
targets,
|
||||
gdk.ACTION_COPY)
|
||||
dest.DragDestAddUriTargets()
|
||||
dest.Connect("drag-data-received", func(ctx *glib.CallbackContext) {
|
||||
sdata := gtk.NewSelectionDataFromNative(unsafe.Pointer(ctx.Args(3)))
|
||||
if sdata != nil {
|
||||
a := (*[2000]uint8)(sdata.GetData())
|
||||
files := strings.Split(string(a[0:sdata.GetLength()-1]), "\n")
|
||||
for i := range files {
|
||||
filename, _, _ := glib.FilenameFromUri(files[i])
|
||||
files[i] = filename
|
||||
}
|
||||
dialog := gtk.NewMessageDialog(
|
||||
window,
|
||||
gtk.DIALOG_MODAL,
|
||||
gtk.MESSAGE_INFO,
|
||||
gtk.BUTTONS_OK,
|
||||
strings.Join(files, "\n"))
|
||||
dialog.SetTitle("D&D")
|
||||
dialog.Response(func() {
|
||||
dialog.Destroy()
|
||||
})
|
||||
dialog.Run()
|
||||
}
|
||||
})
|
||||
vbox.Add(dest)
|
||||
|
||||
window.Add(vbox)
|
||||
|
||||
window.SetSizeRequest(300, 100)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
92
vendor/github.com/mattn/go-gtk/example/drawable/drawable.go
generated
vendored
Normal file
92
vendor/github.com/mattn/go-gtk/example/drawable/drawable.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type point struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK DrawingArea")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
vbox := gtk.NewVBox(true, 0)
|
||||
vbox.SetBorderWidth(5)
|
||||
drawingarea := gtk.NewDrawingArea()
|
||||
|
||||
var p1, p2 point
|
||||
var gdkwin *gdk.Window
|
||||
var pixmap *gdk.Pixmap
|
||||
var gc *gdk.GC
|
||||
p1.x = -1
|
||||
p1.y = -1
|
||||
colors := []string{
|
||||
"black",
|
||||
"gray",
|
||||
"blue",
|
||||
"purple",
|
||||
"red",
|
||||
"orange",
|
||||
"yellow",
|
||||
"green",
|
||||
"darkgreen",
|
||||
}
|
||||
|
||||
drawingarea.Connect("configure-event", func() {
|
||||
if pixmap != nil {
|
||||
pixmap.Unref()
|
||||
}
|
||||
allocation := drawingarea.GetAllocation()
|
||||
pixmap = gdk.NewPixmap(drawingarea.GetWindow().GetDrawable(), allocation.Width, allocation.Height, 24)
|
||||
gc = gdk.NewGC(pixmap.GetDrawable())
|
||||
gc.SetRgbFgColor(gdk.NewColor("white"))
|
||||
pixmap.GetDrawable().DrawRectangle(gc, true, 0, 0, -1, -1)
|
||||
gc.SetRgbFgColor(gdk.NewColor(colors[0]))
|
||||
gc.SetRgbBgColor(gdk.NewColor("white"))
|
||||
})
|
||||
|
||||
drawingarea.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
|
||||
arg := ctx.Args(0)
|
||||
mev := *(**gdk.EventMotion)(unsafe.Pointer(&arg))
|
||||
var mt gdk.ModifierType
|
||||
if mev.IsHint != 0 {
|
||||
gdkwin.GetPointer(&p2.x, &p2.y, &mt)
|
||||
} else {
|
||||
p2.x, p2.y = int(mev.X), int(mev.Y)
|
||||
}
|
||||
if p1.x != -1 && p2.x != -1 && (gdk.EventMask(mt)&gdk.BUTTON_PRESS_MASK) != 0 {
|
||||
pixmap.GetDrawable().DrawLine(gc, p1.x, p1.y, p2.x, p2.y)
|
||||
gdkwin.Invalidate(nil, false)
|
||||
}
|
||||
colors = append(colors[1:], colors[0])
|
||||
gc.SetRgbFgColor(gdk.NewColor(colors[0]))
|
||||
p1 = p2
|
||||
})
|
||||
|
||||
drawingarea.Connect("expose-event", func() {
|
||||
if pixmap == nil {
|
||||
return
|
||||
}
|
||||
gdkwin.GetDrawable().DrawDrawable(gc, pixmap.GetDrawable(), 0, 0, 0, 0, -1, -1)
|
||||
})
|
||||
|
||||
drawingarea.SetEvents(int(gdk.POINTER_MOTION_MASK | gdk.POINTER_MOTION_HINT_MASK | gdk.BUTTON_PRESS_MASK))
|
||||
vbox.Add(drawingarea)
|
||||
|
||||
window.Add(vbox)
|
||||
window.SetSizeRequest(400, 400)
|
||||
window.ShowAll()
|
||||
|
||||
gdkwin = drawingarea.GetWindow()
|
||||
|
||||
gtk.Main()
|
||||
}
|
48
vendor/github.com/mattn/go-gtk/example/event/event.go
generated
vendored
Normal file
48
vendor/github.com/mattn/go-gtk/example/event/event.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Events")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
event := make(chan interface{})
|
||||
|
||||
window.Connect("key-press-event", func(ctx *glib.CallbackContext) {
|
||||
arg := ctx.Args(0)
|
||||
event <- *(**gdk.EventKey)(unsafe.Pointer(&arg))
|
||||
})
|
||||
window.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
|
||||
arg := ctx.Args(0)
|
||||
event <- *(**gdk.EventMotion)(unsafe.Pointer(&arg))
|
||||
})
|
||||
|
||||
go func() {
|
||||
for {
|
||||
e := <-event
|
||||
switch ev := e.(type) {
|
||||
case *gdk.EventKey:
|
||||
fmt.Println("key-press-event:", ev.Keyval)
|
||||
break
|
||||
case *gdk.EventMotion:
|
||||
fmt.Println("motion-notify-event:", int(ev.X), int(ev.Y))
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
window.SetEvents(int(gdk.POINTER_MOTION_MASK | gdk.POINTER_MOTION_HINT_MASK | gdk.BUTTON_PRESS_MASK))
|
||||
window.SetSizeRequest(400, 400)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
59
vendor/github.com/mattn/go-gtk/example/example.mk
generated
vendored
Normal file
59
vendor/github.com/mattn/go-gtk/example/example.mk
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
EXAMPLES := \
|
||||
example/action/action \
|
||||
example/alignment/alignment \
|
||||
example/builder/builder \
|
||||
example/clipboard/clipboard \
|
||||
example/demo/demo \
|
||||
example/arrow/arrow \
|
||||
example/dnd/dnd \
|
||||
example/drawable/drawable \
|
||||
example/event/event \
|
||||
example/expander/expander \
|
||||
example/iconview/iconview \
|
||||
example/listview/listview \
|
||||
example/locale/locale \
|
||||
example/notebook/notebook \
|
||||
example/number/number \
|
||||
example/sourceview/sourceview \
|
||||
example/spinbutton/spinbutton \
|
||||
example/statusicon/statusicon \
|
||||
example/table/table \
|
||||
example/thread/thread \
|
||||
example/toolbar/toolbar \
|
||||
example/treeview/treeview \
|
||||
example/twitterstream/twitterstream
|
||||
|
||||
.PHONY: example
|
||||
example: $(EXAMPLES)
|
||||
@true
|
||||
|
||||
.PHONY: clean-example
|
||||
clean-example:
|
||||
rm -f $(EXAMPLES)
|
||||
|
||||
%: %.go
|
||||
cd $(@D) && go build -x
|
||||
|
||||
example/action/action: example/action/action.go
|
||||
example/alignment/alignment: example/alignment/alignment.go
|
||||
example/builder/builder: example/builder/builder.go
|
||||
example/clipboard/clipboard: example/clipboard/clipboard.go
|
||||
example/demo/demo: example/demo/demo.go
|
||||
example/arrow/arrow: example/arrow/arrow.go
|
||||
example/dnd/dnd: example/dnd/dnd.go
|
||||
example/drawable/drawable: example/drawable/drawable.go
|
||||
example/event/event: example/event/event.go
|
||||
example/expander/expander: example/expander/expander.go
|
||||
example/iconview/iconview: example/iconview/iconview.go
|
||||
example/listview/listview: example/listview/listview.go
|
||||
example/locale/locale: example/locale/locale.go
|
||||
example/notebook/notebook: example/notebook/notebook.go
|
||||
example/number/number: example/number/number.go
|
||||
example/sourceview/sourceview: example/sourceview/sourceview.go
|
||||
example/spinbutton/spinbutton: example/spinbutton/spinbutton.go
|
||||
example/statusicon/statusicon: example/statusicon/statusicon.go
|
||||
example/table/table: example/table/table.go
|
||||
example/thread/thread: example/thread/thread.go
|
||||
example/toolbar/toolbar: example/toolbar/toolbar.go
|
||||
example/treeview/treeview: example/treeview/treeview.go
|
||||
example/twitterstream/twitterstream: example/twitterstream/twitterstream.go
|
24
vendor/github.com/mattn/go-gtk/example/expander/expander.go
generated
vendored
Normal file
24
vendor/github.com/mattn/go-gtk/example/expander/expander.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("We love Expander")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
vbox := gtk.NewVBox(true, 0)
|
||||
vbox.SetBorderWidth(5)
|
||||
expander := gtk.NewExpander("dan the ...")
|
||||
expander.Add(gtk.NewLabel("404 contents not found"))
|
||||
vbox.PackStart(expander, false, false, 0)
|
||||
|
||||
window.Add(vbox)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
40
vendor/github.com/mattn/go-gtk/example/iconview/iconview.go
generated
vendored
Normal file
40
vendor/github.com/mattn/go-gtk/example/iconview/iconview.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Icon View")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
|
||||
store := gtk.NewListStore(gdkpixbuf.GetType(), glib.G_TYPE_STRING)
|
||||
iconview := gtk.NewIconViewWithModel(store)
|
||||
iconview.SetPixbufColumn(0)
|
||||
iconview.SetTextColumn(1)
|
||||
swin.Add(iconview)
|
||||
|
||||
gtk.StockListIDs().ForEach(func(d unsafe.Pointer, v interface{}) {
|
||||
id := glib.GPtrToString(d)
|
||||
var iter gtk.TreeIter
|
||||
store.Append(&iter)
|
||||
store.Set(&iter,
|
||||
0, gtk.NewImage().RenderIcon(id, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf,
|
||||
1, id)
|
||||
})
|
||||
|
||||
window.Add(swin)
|
||||
window.SetSizeRequest(500, 200)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
21
vendor/github.com/mattn/go-gtk/example/idle/idle.go
generated
vendored
Normal file
21
vendor/github.com/mattn/go-gtk/example/idle/idle.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
glib.IdleAdd(func() bool {
|
||||
fmt.Println("start")
|
||||
return false
|
||||
})
|
||||
glib.TimeoutAdd(1000, func() bool {
|
||||
fmt.Println(fmt.Sprintf("%v", time.Now()))
|
||||
return true
|
||||
})
|
||||
|
||||
glib.NewMainLoop(nil, false).Run()
|
||||
}
|
46
vendor/github.com/mattn/go-gtk/example/listview/listview.go
generated
vendored
Normal file
46
vendor/github.com/mattn/go-gtk/example/listview/listview.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Stock Icons")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
|
||||
store := gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_BOOL, gdkpixbuf.GetType())
|
||||
treeview := gtk.NewTreeView()
|
||||
swin.Add(treeview)
|
||||
|
||||
treeview.SetModel(store)
|
||||
treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("name", gtk.NewCellRendererText(), "text", 0))
|
||||
treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("check", gtk.NewCellRendererToggle(), "active", 1))
|
||||
treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("icon", gtk.NewCellRendererPixbuf(), "pixbuf", 2))
|
||||
n := 0
|
||||
gtk.StockListIDs().ForEach(func(d unsafe.Pointer, v interface{}) {
|
||||
id := glib.GPtrToString(d)
|
||||
var iter gtk.TreeIter
|
||||
store.Append(&iter)
|
||||
store.Set(&iter,
|
||||
0, id,
|
||||
1, (n == 1),
|
||||
2, gtk.NewImage().RenderIcon(id, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf,
|
||||
)
|
||||
n = 1 - n
|
||||
})
|
||||
|
||||
window.Add(swin)
|
||||
window.SetSizeRequest(400, 200)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
17
vendor/github.com/mattn/go-gtk/example/locale/locale.go
generated
vendored
Normal file
17
vendor/github.com/mattn/go-gtk/example/locale/locale.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import "github.com/mattn/go-gtk/gtk"
|
||||
import "github.com/mattn/go-gtk/glib"
|
||||
import "fmt"
|
||||
import "syscall"
|
||||
|
||||
func main() {
|
||||
gtk.SetLocale()
|
||||
|
||||
bs, _, _, err := glib.LocaleFromUtf8("こんにちわ世界\n")
|
||||
if err == nil {
|
||||
syscall.Write(syscall.Stdout, bs)
|
||||
} else {
|
||||
fmt.Println(err.Message())
|
||||
}
|
||||
}
|
42
vendor/github.com/mattn/go-gtk/example/notebook/notebook.go
generated
vendored
Normal file
42
vendor/github.com/mattn/go-gtk/example/notebook/notebook.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Notebook")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
notebook := gtk.NewNotebook()
|
||||
for n := 1; n <= 10; n++ {
|
||||
page := gtk.NewFrame("demo" + strconv.Itoa(n))
|
||||
notebook.AppendPage(page, gtk.NewLabel("demo"+strconv.Itoa(n)))
|
||||
|
||||
vbox := gtk.NewHBox(false, 1)
|
||||
|
||||
prev := gtk.NewButtonWithLabel("go prev")
|
||||
prev.Clicked(func() {
|
||||
notebook.PrevPage()
|
||||
})
|
||||
vbox.Add(prev)
|
||||
|
||||
next := gtk.NewButtonWithLabel("go next")
|
||||
next.Clicked(func() {
|
||||
notebook.NextPage()
|
||||
})
|
||||
vbox.Add(next)
|
||||
|
||||
page.Add(vbox)
|
||||
}
|
||||
|
||||
window.Add(notebook)
|
||||
window.SetSizeRequest(400, 200)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
56
vendor/github.com/mattn/go-gtk/example/number/number.go
generated
vendored
Normal file
56
vendor/github.com/mattn/go-gtk/example/number/number.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
|
||||
dialog := gtk.NewDialog()
|
||||
dialog.SetTitle("number input")
|
||||
|
||||
vbox := dialog.GetVBox()
|
||||
|
||||
label := gtk.NewLabel("Numnber:")
|
||||
vbox.Add(label)
|
||||
|
||||
input := gtk.NewEntry()
|
||||
input.SetEditable(true)
|
||||
vbox.Add(input)
|
||||
|
||||
input.Connect("insert-text", func(ctx *glib.CallbackContext) {
|
||||
a := (*[2000]uint8)(unsafe.Pointer(ctx.Args(0)))
|
||||
p := (*int)(unsafe.Pointer(ctx.Args(2)))
|
||||
i := 0
|
||||
for a[i] != 0 {
|
||||
i++
|
||||
}
|
||||
s := string(a[0:i])
|
||||
if s == "." {
|
||||
if *p == 0 {
|
||||
input.StopEmission("insert-text")
|
||||
}
|
||||
} else {
|
||||
_, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
input.StopEmission("insert-text")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
button := gtk.NewButtonWithLabel("OK")
|
||||
button.Connect("clicked", func() {
|
||||
fmt.Println(input.GetText())
|
||||
gtk.MainQuit()
|
||||
})
|
||||
vbox.Add(button)
|
||||
|
||||
dialog.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
61
vendor/github.com/mattn/go-gtk/example/sourceview/sourceview.go
generated
vendored
Normal file
61
vendor/github.com/mattn/go-gtk/example/sourceview/sourceview.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
gsv "github.com/mattn/go-gtk/gtksourceview"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("SourceView")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
swin.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
swin.SetShadowType(gtk.SHADOW_IN)
|
||||
sourcebuffer := gsv.NewSourceBufferWithLanguage(gsv.SourceLanguageManagerGetDefault().GetLanguage("cpp"))
|
||||
sourceview := gsv.NewSourceViewWithBuffer(sourcebuffer)
|
||||
|
||||
var start gtk.TextIter
|
||||
sourcebuffer.GetStartIter(&start)
|
||||
sourcebuffer.BeginNotUndoableAction()
|
||||
sourcebuffer.Insert(&start, `#include <iostream>
|
||||
template<class T>
|
||||
struct foo_base {
|
||||
T operator+(T const &rhs) const {
|
||||
T tmp(static_cast<T const &>(*this));
|
||||
tmp += rhs;
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
class foo : public foo_base<foo> {
|
||||
private:
|
||||
int v;
|
||||
public:
|
||||
foo(int v) : v(v) {}
|
||||
foo &operator+=(foo const &rhs){
|
||||
this->v += rhs.v;
|
||||
return *this;
|
||||
}
|
||||
operator int() { return v; }
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
foo a(1), b(2);
|
||||
a += b;
|
||||
std::cout << (int)a << std::endl;
|
||||
}
|
||||
`)
|
||||
sourcebuffer.EndNotUndoableAction()
|
||||
|
||||
swin.Add(sourceview)
|
||||
|
||||
window.Add(swin)
|
||||
window.SetSizeRequest(400, 300)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
56
vendor/github.com/mattn/go-gtk/example/spinbutton/spinbutton.go
generated
vendored
Normal file
56
vendor/github.com/mattn/go-gtk/example/spinbutton/spinbutton.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("GTK Go!")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
fmt.Println("got destroy!", ctx.Data().(string))
|
||||
gtk.MainQuit()
|
||||
}, "foo")
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkHBox
|
||||
//--------------------------------------------------------
|
||||
fixed := gtk.NewFixed()
|
||||
|
||||
//--------------------------------------------------------
|
||||
// GtkSpinButton
|
||||
//--------------------------------------------------------
|
||||
spinbutton1 := gtk.NewSpinButtonWithRange(1.0, 10.0, 1.0)
|
||||
spinbutton1.SetDigits(3)
|
||||
spinbutton1.Spin(gtk.SPIN_STEP_FORWARD, 7.0)
|
||||
fixed.Put(spinbutton1, 40, 50)
|
||||
|
||||
spinbutton1.OnValueChanged(func() {
|
||||
val := spinbutton1.GetValueAsInt()
|
||||
fval := spinbutton1.GetValue()
|
||||
fmt.Println("SpinButton changed, new value: " + strconv.Itoa(val) + " | " + strconv.FormatFloat(fval, 'f', 2, 64))
|
||||
min, max := spinbutton1.GetRange()
|
||||
fmt.Println("Range: " + strconv.FormatFloat(min, 'f', 2, 64) + " " + strconv.FormatFloat(max, 'f', 2, 64))
|
||||
fmt.Println("Digits: " + strconv.Itoa(int(spinbutton1.GetDigits())))
|
||||
})
|
||||
|
||||
adjustment := gtk.NewAdjustment(2.0, 1.0, 8.0, 2.0, 0.0, 0.0)
|
||||
spinbutton2 := gtk.NewSpinButton(adjustment, 1.0, 1)
|
||||
spinbutton2.SetRange(0.0, 20.0)
|
||||
spinbutton2.SetValue(18.0)
|
||||
spinbutton2.SetIncrements(2.0, 4.0)
|
||||
fixed.Put(spinbutton2, 150, 50)
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Event
|
||||
//--------------------------------------------------------
|
||||
window.Add(fixed)
|
||||
window.SetSizeRequest(600, 600)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
40
vendor/github.com/mattn/go-gtk/example/statusicon/statusicon.go
generated
vendored
Normal file
40
vendor/github.com/mattn/go-gtk/example/statusicon/statusicon.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
|
||||
glib.SetApplicationName("go-gtk-statusicon-example")
|
||||
|
||||
mi := gtk.NewMenuItemWithLabel("Popup!")
|
||||
mi.Connect("activate", func() {
|
||||
gtk.MainQuit()
|
||||
})
|
||||
nm := gtk.NewMenu()
|
||||
nm.Append(mi)
|
||||
nm.ShowAll()
|
||||
|
||||
si := gtk.NewStatusIconFromStock(gtk.STOCK_FILE)
|
||||
si.SetTitle("StatusIcon Example")
|
||||
si.SetTooltipMarkup("StatusIcon Example")
|
||||
si.Connect("popup-menu", func(cbx *glib.CallbackContext) {
|
||||
nm.Popup(nil, nil, gtk.StatusIconPositionMenu, si, uint(cbx.Args(0)), uint32(cbx.Args(1)))
|
||||
})
|
||||
|
||||
fmt.Println(`
|
||||
Can you see statusicon in systray?
|
||||
If you don't see it and if you use 'unity', try following.
|
||||
|
||||
# gsettings set com.canonical.Unity.Panel systray-whitelist \
|
||||
"$(gsettings get com.canonical.Unity.Panel systray-whitelist \|
|
||||
sed -e "s/]$/, 'go-gtk-statusicon-example']/")"
|
||||
`)
|
||||
|
||||
gtk.Main()
|
||||
}
|
31
vendor/github.com/mattn/go-gtk/example/table/table.go
generated
vendored
Normal file
31
vendor/github.com/mattn/go-gtk/example/table/table.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Table")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
swin.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
|
||||
table := gtk.NewTable(5, 5, false)
|
||||
for y := uint(0); y < 5; y++ {
|
||||
for x := uint(0); x < 5; x++ {
|
||||
table.Attach(gtk.NewButtonWithLabel(fmt.Sprintf("%02d:%02d", x, y)), x, x+1, y, y+1, gtk.FILL, gtk.FILL, 5, 5)
|
||||
}
|
||||
}
|
||||
swin.AddWithViewPort(table)
|
||||
|
||||
window.Add(swin)
|
||||
window.SetDefaultSize(200, 200)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
55
vendor/github.com/mattn/go-gtk/example/textview/textview.go
generated
vendored
Normal file
55
vendor/github.com/mattn/go-gtk/example/textview/textview.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("GTK Go!")
|
||||
window.SetIconName("textview")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
textview := gtk.NewTextView()
|
||||
textview.SetEditable(true)
|
||||
textview.SetCursorVisible(true)
|
||||
var iter gtk.TextIter
|
||||
buffer := textview.GetBuffer()
|
||||
|
||||
buffer.GetStartIter(&iter)
|
||||
buffer.Insert(&iter, "Hello ")
|
||||
|
||||
tag := buffer.CreateTag("bold", map[string]string{"background": "#FF0000", "weight": "700"})
|
||||
buffer.InsertWithTag(&iter, "Google!", tag)
|
||||
|
||||
u := "http://www.google.com"
|
||||
tag.SetData("tag-name", unsafe.Pointer(&u))
|
||||
textview.Connect("event-after", func(ctx *glib.CallbackContext) {
|
||||
arg := ctx.Args(0)
|
||||
if ev := *(**gdk.EventAny)(unsafe.Pointer(&arg)); ev.Type != gdk.BUTTON_RELEASE {
|
||||
return
|
||||
}
|
||||
ev := *(**gdk.EventButton)(unsafe.Pointer(&arg))
|
||||
var iter gtk.TextIter
|
||||
textview.GetIterAtLocation(&iter, int(ev.X), int(ev.Y))
|
||||
tags := iter.GetTags()
|
||||
for n := uint(0); n < tags.Length(); n++ {
|
||||
vv := tags.NthData(n)
|
||||
tag := gtk.NewTextTagFromPointer(vv)
|
||||
u := *(*string)(tag.GetData("tag-name"))
|
||||
fmt.Println(u)
|
||||
}
|
||||
})
|
||||
|
||||
window.Add(textview)
|
||||
window.SetSizeRequest(600, 600)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
51
vendor/github.com/mattn/go-gtk/example/thread/thread.go
generated
vendored
Normal file
51
vendor/github.com/mattn/go-gtk/example/thread/thread.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
runtime.GOMAXPROCS(10)
|
||||
glib.ThreadInit(nil)
|
||||
gdk.ThreadsInit()
|
||||
gdk.ThreadsEnter()
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
vbox := gtk.NewVBox(false, 1)
|
||||
|
||||
label1 := gtk.NewLabel("")
|
||||
vbox.Add(label1)
|
||||
label2 := gtk.NewLabel("")
|
||||
vbox.Add(label2)
|
||||
|
||||
window.Add(vbox)
|
||||
|
||||
window.SetSizeRequest(100, 100)
|
||||
window.ShowAll()
|
||||
time.Sleep(1000 * 1000 * 100)
|
||||
go (func() {
|
||||
for i := 0; i < 300000; i++ {
|
||||
gdk.ThreadsEnter()
|
||||
label1.SetLabel(strconv.Itoa(i))
|
||||
gdk.ThreadsLeave()
|
||||
}
|
||||
gtk.MainQuit()
|
||||
})()
|
||||
go (func() {
|
||||
for i := 300000; i >= 0; i-- {
|
||||
gdk.ThreadsEnter()
|
||||
label2.SetLabel(strconv.Itoa(i))
|
||||
gdk.ThreadsLeave()
|
||||
}
|
||||
gtk.MainQuit()
|
||||
})()
|
||||
gtk.Main()
|
||||
}
|
108
vendor/github.com/mattn/go-gtk/example/toolbar/toolbar.go
generated
vendored
Normal file
108
vendor/github.com/mattn/go-gtk/example/toolbar/toolbar.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("GTK Go!")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
gtk.MainQuit()
|
||||
}, "")
|
||||
|
||||
vbox := gtk.NewVBox(false, 0)
|
||||
|
||||
toolbar := gtk.NewToolbar()
|
||||
toolbar.SetStyle(gtk.TOOLBAR_ICONS)
|
||||
vbox.PackStart(toolbar, false, false, 5)
|
||||
|
||||
btnnew := gtk.NewToolButtonFromStock(gtk.STOCK_NEW)
|
||||
btnclose := gtk.NewToolButtonFromStock(gtk.STOCK_CLOSE)
|
||||
separator := gtk.NewSeparatorToolItem()
|
||||
btncustom := gtk.NewToolButton(nil, "Custom")
|
||||
btnmenu := gtk.NewMenuToolButtonFromStock("gtk.STOCK_CLOSE")
|
||||
btnmenu.SetArrowTooltipText("This is a tool tip")
|
||||
|
||||
btnnew.OnClicked(onToolButtonClicked)
|
||||
btnclose.OnClicked(onToolButtonClicked)
|
||||
btncustom.OnClicked(onToolButtonClicked)
|
||||
|
||||
toolmenu := gtk.NewMenu()
|
||||
menuitem := gtk.NewMenuItemWithMnemonic("8")
|
||||
menuitem.Show()
|
||||
toolmenu.Append(menuitem)
|
||||
menuitem = gtk.NewMenuItemWithMnemonic("16")
|
||||
menuitem.Show()
|
||||
toolmenu.Append(menuitem)
|
||||
menuitem = gtk.NewMenuItemWithMnemonic("32")
|
||||
menuitem.Show()
|
||||
toolmenu.Append(menuitem)
|
||||
btnmenu.SetMenu(toolmenu)
|
||||
|
||||
toolbar.Insert(btnnew, -1)
|
||||
toolbar.Insert(btnclose, -1)
|
||||
toolbar.Insert(separator, -1)
|
||||
toolbar.Insert(btncustom, -1)
|
||||
toolbar.Insert(btnmenu, -1)
|
||||
|
||||
hbox := gtk.NewHBox(false, 0)
|
||||
vbox.PackStart(hbox, true, true, 0)
|
||||
|
||||
toolbar2 := gtk.NewToolbar()
|
||||
toolbar2.SetOrientation(gtk.ORIENTATION_VERTICAL)
|
||||
hbox.PackStart(toolbar2, false, false, 5)
|
||||
btnhelp := gtk.NewToolButtonFromStock(gtk.STOCK_HELP)
|
||||
btnhelp.OnClicked(onToolButtonClicked)
|
||||
toolbar2.Insert(btnhelp, -1)
|
||||
|
||||
btntoggle := gtk.NewToggleToolButton()
|
||||
btntoggle2 := gtk.NewToggleToolButtonFromStock(gtk.STOCK_ITALIC)
|
||||
toolbar2.Insert(btntoggle, -1)
|
||||
toolbar2.Insert(btntoggle2, -1)
|
||||
|
||||
for i := 0; i < toolbar.GetNItems(); i++ {
|
||||
gti := toolbar.GetNthItem(i)
|
||||
switch gti.(type) {
|
||||
case *gtk.ToolButton:
|
||||
fmt.Printf("toolbar[%d] is a *gtk.ToolButton\n", i)
|
||||
w := gti.(*gtk.ToolButton).GetIconWidget()
|
||||
gti.(*gtk.ToolButton).SetIconWidget(w)
|
||||
case *gtk.ToggleToolButton:
|
||||
fmt.Printf("toolbar[%d] is a *gtk.ToggleToolButton\n", i)
|
||||
gti.(*gtk.ToggleToolButton).SetActive(true)
|
||||
case *gtk.SeparatorToolItem:
|
||||
fmt.Printf("toolbar[%d] is a *gtk.SeparatorToolItem\n", i)
|
||||
default:
|
||||
fmt.Printf("toolbar: Item is of unknown type\n")
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < toolbar2.GetNItems(); i++ {
|
||||
gti := toolbar2.GetNthItem(i)
|
||||
switch gti.(type) {
|
||||
case *gtk.ToolButton:
|
||||
fmt.Printf("toolbar2[%d] is a *gtk.ToolButton\n", i)
|
||||
case *gtk.ToggleToolButton:
|
||||
fmt.Printf("toolbar2[%d] is a *gtk.ToggleToolButton\n", i)
|
||||
gti.(*gtk.ToggleToolButton).SetActive(true)
|
||||
case *gtk.SeparatorToolItem:
|
||||
fmt.Printf("toolbar2[%d] is a *gtk.SeparatorToolItem\n", i)
|
||||
default:
|
||||
fmt.Printf("toolbar2: Item is of unknown type\n")
|
||||
}
|
||||
}
|
||||
|
||||
window.Add(vbox)
|
||||
window.SetSizeRequest(600, 600)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
||||
|
||||
func onToolButtonClicked() {
|
||||
fmt.Println("ToolButton clicked")
|
||||
}
|
78
vendor/github.com/mattn/go-gtk/example/toolpalette/toolpalette.go
generated
vendored
Normal file
78
vendor/github.com/mattn/go-gtk/example/toolpalette/toolpalette.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("GTK Go!")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
gtk.MainQuit()
|
||||
}, "")
|
||||
|
||||
box := gtk.NewHPaned()
|
||||
|
||||
palette := gtk.NewToolPalette()
|
||||
group := gtk.NewToolItemGroup("Tools")
|
||||
b := gtk.NewToolButtonFromStock(gtk.STOCK_NEW)
|
||||
b.OnClicked(func() { fmt.Println("You clicked new!") })
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_CLOSE)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_REDO)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_REFRESH)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_QUIT)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_YES)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_NO)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_PRINT)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_NETWORK)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_INFO)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_HOME)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_INDEX)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_FIND)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_FILE)
|
||||
group.Insert(b, -1)
|
||||
b = gtk.NewToolButtonFromStock(gtk.STOCK_EXECUTE)
|
||||
group.Insert(b, -1)
|
||||
palette.Add(group)
|
||||
|
||||
bcopy := gtk.NewToolButtonFromStock(gtk.STOCK_COPY)
|
||||
bcut := gtk.NewToolButtonFromStock(gtk.STOCK_CUT)
|
||||
bdelete := gtk.NewToolButtonFromStock(gtk.STOCK_DELETE)
|
||||
|
||||
group = gtk.NewToolItemGroup("Stuff")
|
||||
group.Insert(bcopy, -1)
|
||||
group.Insert(bcut, -1)
|
||||
group.Insert(bdelete, -1)
|
||||
palette.Add(group)
|
||||
|
||||
frame := gtk.NewVBox(false, 1)
|
||||
align := gtk.NewAlignment(0, 0, 0, 0)
|
||||
image := gtk.NewImageFromFile("./turkey.jpg")
|
||||
align.Add(image)
|
||||
frame.Add(align)
|
||||
|
||||
box.Pack1(palette, true, false)
|
||||
box.Pack2(frame, false, false)
|
||||
|
||||
window.Add(box)
|
||||
window.SetSizeRequest(600, 600)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
BIN
vendor/github.com/mattn/go-gtk/example/toolpalette/turkey.jpg
generated
vendored
Normal file
BIN
vendor/github.com/mattn/go-gtk/example/toolpalette/turkey.jpg
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
60
vendor/github.com/mattn/go-gtk/example/treeview/treeview.go
generated
vendored
Normal file
60
vendor/github.com/mattn/go-gtk/example/treeview/treeview.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("GTK Folder View")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
swin := gtk.NewScrolledWindow(nil, nil)
|
||||
|
||||
store := gtk.NewTreeStore(gdkpixbuf.GetType(), glib.G_TYPE_STRING)
|
||||
treeview := gtk.NewTreeView()
|
||||
swin.Add(treeview)
|
||||
|
||||
treeview.SetModel(store.ToTreeModel())
|
||||
treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("pixbuf", gtk.NewCellRendererPixbuf(), "pixbuf", 0))
|
||||
treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("text", gtk.NewCellRendererText(), "text", 1))
|
||||
|
||||
for n := 1; n <= 10; n++ {
|
||||
var iter1, iter2, iter3 gtk.TreeIter
|
||||
store.Append(&iter1, nil)
|
||||
store.Set(&iter1, gtk.NewImage().RenderIcon(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf, "Folder"+strconv.Itoa(n))
|
||||
store.Append(&iter2, &iter1)
|
||||
store.Set(&iter2, gtk.NewImage().RenderIcon(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf, "SubFolder"+strconv.Itoa(n))
|
||||
store.Append(&iter3, &iter2)
|
||||
store.Set(&iter3, gtk.NewImage().RenderIcon(gtk.STOCK_FILE, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf, "File"+strconv.Itoa(n))
|
||||
}
|
||||
|
||||
treeview.Connect("row_activated", func() {
|
||||
var path *gtk.TreePath
|
||||
var column *gtk.TreeViewColumn
|
||||
treeview.GetCursor(&path, &column)
|
||||
mes := "TreePath is: " + path.String()
|
||||
dialog := gtk.NewMessageDialog(
|
||||
treeview.GetTopLevelAsWindow(),
|
||||
gtk.DIALOG_MODAL,
|
||||
gtk.MESSAGE_INFO,
|
||||
gtk.BUTTONS_OK,
|
||||
mes)
|
||||
dialog.SetTitle("TreePath")
|
||||
dialog.Response(func() {
|
||||
dialog.Destroy()
|
||||
})
|
||||
dialog.Run()
|
||||
})
|
||||
|
||||
window.Add(swin)
|
||||
window.SetSizeRequest(400, 200)
|
||||
window.ShowAll()
|
||||
|
||||
gtk.Main()
|
||||
}
|
6
vendor/github.com/mattn/go-gtk/example/twitterstream/settings.json.example
generated
vendored
Normal file
6
vendor/github.com/mattn/go-gtk/example/twitterstream/settings.json.example
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"AccessSecret": "ACCCESS_TOKEN_SECRET",
|
||||
"AccessToken": "ACCESS_TOKEN",
|
||||
"ClientSecret": "CLIENT_SECRET",
|
||||
"ClientToken": "CLIENT_TOKEN"
|
||||
}
|
249
vendor/github.com/mattn/go-gtk/example/twitterstream/twitterstream.go
generated
vendored
Normal file
249
vendor/github.com/mattn/go-gtk/example/twitterstream/twitterstream.go
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/garyburd/go-oauth/oauth"
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
var (
|
||||
alive = true
|
||||
)
|
||||
|
||||
func readURL(url string) ([]byte, *http.Response) {
|
||||
r, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
var b []byte
|
||||
if b, err = ioutil.ReadAll(r.Body); err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
return b, r
|
||||
}
|
||||
|
||||
func bytes2pixbuf(data []byte, typ string) *gdkpixbuf.Pixbuf {
|
||||
var loader *gdkpixbuf.Loader
|
||||
if strings.Index(typ, "jpeg") >= 0 {
|
||||
loader, _ = gdkpixbuf.NewLoaderWithMimeType("image/jpeg")
|
||||
} else {
|
||||
loader, _ = gdkpixbuf.NewLoaderWithMimeType("image/png")
|
||||
}
|
||||
loader.SetSize(24, 24)
|
||||
loader.Write(data)
|
||||
loader.Close()
|
||||
return loader.GetPixbuf()
|
||||
}
|
||||
|
||||
type tweet struct {
|
||||
Text string
|
||||
Identifier string `json:"id_str"`
|
||||
Source string
|
||||
User struct {
|
||||
Name string
|
||||
ScreenName string `json:"screen_name"`
|
||||
FollowersCount int `json:"followers_count"`
|
||||
ProfileImageUrl string `json:"profile_image_url"`
|
||||
}
|
||||
Place *struct {
|
||||
Id string
|
||||
FullName string `json:"full_name"`
|
||||
}
|
||||
Entities struct {
|
||||
HashTags []struct {
|
||||
Indices [2]int
|
||||
Text string
|
||||
}
|
||||
UserMentions []struct {
|
||||
Indices [2]int
|
||||
ScreenName string `json:"screen_name"`
|
||||
} `json:"user_mentions"`
|
||||
Urls []struct {
|
||||
Indices [2]int
|
||||
Url string
|
||||
DisplayUrl string `json:"display_url"`
|
||||
ExpandedUrl *string `json:"expanded_url"`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stream(client *oauth.Client, cred *oauth.Credentials, f func(*tweet)) {
|
||||
param := make(url.Values)
|
||||
uri := "https://userstream.twitter.com/1.1/user.json"
|
||||
client.SignParam(cred, "GET", uri, param)
|
||||
uri = uri + "?" + param.Encode()
|
||||
res, err := http.Get(uri)
|
||||
if err != nil {
|
||||
log.Fatal("failed to get tweets:", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
log.Fatal("failed to get tweets:", err)
|
||||
}
|
||||
var buf *bufio.Reader
|
||||
if res.Header.Get("Content-Encoding") == "gzip" {
|
||||
gr, err := gzip.NewReader(res.Body)
|
||||
if err != nil {
|
||||
log.Fatal("failed to make gzip decoder:", err)
|
||||
}
|
||||
buf = bufio.NewReader(gr)
|
||||
} else {
|
||||
buf = bufio.NewReader(res.Body)
|
||||
}
|
||||
var last []byte
|
||||
for alive {
|
||||
b, _, err := buf.ReadLine()
|
||||
last = append(last, b...)
|
||||
var t tweet
|
||||
err = json.Unmarshal(last, &t)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
last = []byte{}
|
||||
if t.Text == "" {
|
||||
continue
|
||||
}
|
||||
f(&t)
|
||||
}
|
||||
}
|
||||
|
||||
func post(client *oauth.Client, cred *oauth.Credentials, s string) {
|
||||
param := make(url.Values)
|
||||
param.Set("status", s)
|
||||
uri := "https://api.twitter.com/1.1/statuses/update.json"
|
||||
client.SignParam(cred, "POST", uri, param)
|
||||
res, err := http.PostForm(uri, url.Values(param))
|
||||
if err != nil {
|
||||
log.Println("failed to post tweet:", err)
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
log.Println("failed to get timeline:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func display(t *tweet, buffer *gtk.TextBuffer, tag *gtk.TextTag) {
|
||||
var iter gtk.TextIter
|
||||
pixbufbytes, resp := readURL(t.User.ProfileImageUrl)
|
||||
buffer.GetStartIter(&iter)
|
||||
if resp != nil {
|
||||
buffer.InsertPixbuf(&iter, bytes2pixbuf(pixbufbytes, resp.Header.Get("Content-Type")))
|
||||
}
|
||||
buffer.Insert(&iter, " ")
|
||||
buffer.InsertWithTag(&iter, t.User.ScreenName, tag)
|
||||
buffer.Insert(&iter, ":"+t.Text+"\n")
|
||||
gtk.MainIterationDo(false)
|
||||
}
|
||||
|
||||
func show(client *oauth.Client, cred *oauth.Credentials, f func(t *tweet)) {
|
||||
param := make(url.Values)
|
||||
uri := "https://api.twitter.com/1.1/statuses/home_timeline.json"
|
||||
client.SignParam(cred, "GET", uri, param)
|
||||
uri = uri + "?" + param.Encode()
|
||||
res, err := http.Get(uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
var tweets []tweet
|
||||
json.NewDecoder(res.Body).Decode(&tweets)
|
||||
for _, t := range tweets {
|
||||
f(&t)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
b, err := ioutil.ReadFile("settings.json")
|
||||
if err != nil {
|
||||
fmt.Println(`"settings.json" not found: `, err)
|
||||
return
|
||||
}
|
||||
var config map[string]string
|
||||
err = json.Unmarshal(b, &config)
|
||||
if err != nil {
|
||||
fmt.Println(`can't read "settings.json": `, err)
|
||||
return
|
||||
}
|
||||
client := &oauth.Client{Credentials: oauth.Credentials{config["ClientToken"], config["ClientSecret"]}}
|
||||
cred := &oauth.Credentials{config["AccessToken"], config["AccessSecret"]}
|
||||
|
||||
runtime.LockOSThread()
|
||||
gtk.Init(&os.Args)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetTitle("Twitter!")
|
||||
window.Connect("destroy", gtk.MainQuit)
|
||||
|
||||
vbox := gtk.NewVBox(false, 1)
|
||||
|
||||
scrolledwin := gtk.NewScrolledWindow(nil, nil)
|
||||
textview := gtk.NewTextView()
|
||||
textview.SetEditable(false)
|
||||
textview.SetCursorVisible(false)
|
||||
scrolledwin.Add(textview)
|
||||
vbox.Add(scrolledwin)
|
||||
|
||||
buffer := textview.GetBuffer()
|
||||
tag := buffer.CreateTag("blue", map[string]string{"foreground": "#0000FF", "weight": "700"})
|
||||
|
||||
hbox := gtk.NewHBox(false, 1)
|
||||
vbox.PackEnd(hbox, false, true, 5)
|
||||
|
||||
label := gtk.NewLabel("Tweet")
|
||||
hbox.PackStart(label, false, false, 5)
|
||||
text := gtk.NewEntry()
|
||||
hbox.PackEnd(text, true, true, 5)
|
||||
|
||||
text.Connect("activate", func() {
|
||||
t := text.GetText()
|
||||
text.SetText("")
|
||||
post(client, cred, t)
|
||||
})
|
||||
|
||||
window.Add(vbox)
|
||||
window.SetSizeRequest(800, 500)
|
||||
window.ShowAll()
|
||||
|
||||
var mutex sync.Mutex
|
||||
|
||||
go func() {
|
||||
show(client, cred, func(t *tweet) {
|
||||
mutex.Lock()
|
||||
display(t, buffer, tag)
|
||||
mutex.Unlock()
|
||||
})
|
||||
|
||||
stream(client, cred, func(t *tweet) {
|
||||
mutex.Lock()
|
||||
display(t, buffer, tag)
|
||||
var start, end gtk.TextIter
|
||||
buffer.GetIterAtLine(&start, buffer.GetLineCount()-2)
|
||||
buffer.GetEndIter(&end)
|
||||
buffer.Delete(&start, &end)
|
||||
mutex.Unlock()
|
||||
})
|
||||
}()
|
||||
|
||||
for alive {
|
||||
mutex.Lock()
|
||||
alive = gtk.MainIterationDo(false)
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
3008
vendor/github.com/mattn/go-gtk/gdk/gdk.go
generated
vendored
Normal file
3008
vendor/github.com/mattn/go-gtk/gdk/gdk.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23
vendor/github.com/mattn/go-gtk/gdk/gdk.go.h
generated
vendored
Normal file
23
vendor/github.com/mattn/go-gtk/gdk/gdk.go.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef GO_GDK_H
|
||||
#define GO_GDK_H
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
static gchar* toGstr(char* s) { return (gchar*)s; }
|
||||
|
||||
static void freeCstr(char* s) { free(s); }
|
||||
|
||||
static GdkWindow* toGdkWindow(void* w) { return GDK_WINDOW(w); }
|
||||
static GdkDragContext* toGdkDragContext(void* l) { return (GdkDragContext*)l; }
|
||||
static GdkFont* toGdkFont(void* l) { return (GdkFont*)l; }
|
||||
|
||||
static void* _gdk_display_get_default() {
|
||||
return (void*) gdk_display_get_default();
|
||||
}
|
||||
|
||||
#endif
|
1
vendor/github.com/mattn/go-gtk/gdk/gdk_freebsd.go
generated
vendored
Symbolic link
1
vendor/github.com/mattn/go-gtk/gdk/gdk_freebsd.go
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
gdk_linux.go
|
15
vendor/github.com/mattn/go-gtk/gdk/gdk_linux.go
generated
vendored
Normal file
15
vendor/github.com/mattn/go-gtk/gdk/gdk_linux.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gdk
|
||||
|
||||
/*
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
// #cgo pkg-config: gdk-2.0 gthread-2.0
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func (v *Window) GetNativeWindowID() int32 {
|
||||
return int32(C.gdk_x11_drawable_get_xid((*C.GdkDrawable)(unsafe.Pointer(v.GWindow))))
|
||||
}
|
33
vendor/github.com/mattn/go-gtk/gdk/gdk_quartz_darwin.go
generated
vendored
Normal file
33
vendor/github.com/mattn/go-gtk/gdk/gdk_quartz_darwin.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// +build !with-x11
|
||||
|
||||
package gdk
|
||||
|
||||
/*
|
||||
#cgo pkg-config: gdk-2.0 gthread-2.0
|
||||
#cgo CFLAGS: -x objective-c
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkquartz.h>
|
||||
|
||||
// Must return void* to avoid "struct size calculation error off=8 bytesize=0"
|
||||
// See:
|
||||
// - https://github.com/golang/go/issues/12065
|
||||
// - http://thread0.me/2015/07/gogoa-cocoa-bindings-for-go/
|
||||
void* getNsWindow(GdkWindow *w) {
|
||||
return (void*) gdk_quartz_window_get_nswindow(w);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type NSWindow struct {
|
||||
ID unsafe.Pointer
|
||||
}
|
||||
|
||||
func (v *Window) GetNativeWindow() *NSWindow {
|
||||
return &NSWindow{
|
||||
unsafe.Pointer(C.getNsWindow(v.GWindow)),
|
||||
}
|
||||
}
|
15
vendor/github.com/mattn/go-gtk/gdk/gdk_windows.go
generated
vendored
Normal file
15
vendor/github.com/mattn/go-gtk/gdk/gdk_windows.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gdk
|
||||
|
||||
/*
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkwin32.h>
|
||||
// #cgo pkg-config: gdk-2.0 gthread-2.0
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func (v *Window) GetNativeWindowID() int32 {
|
||||
return int32(uintptr(unsafe.Pointer(C.gdk_win32_drawable_get_handle((*C.GdkDrawable)(unsafe.Pointer(v.GWindow))))))
|
||||
}
|
16
vendor/github.com/mattn/go-gtk/gdk/gdk_x11_darwin.go
generated
vendored
Normal file
16
vendor/github.com/mattn/go-gtk/gdk/gdk_x11_darwin.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// +build with-x11
|
||||
|
||||
package gdk
|
||||
|
||||
/*
|
||||
#cgo pkg-config: gdk-2.0 gthread-2.0
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func (v *Window) GetNativeWindowID() int32 {
|
||||
return int32(C.gdk_x11_drawable_get_xid((*C.GdkDrawable)(unsafe.Pointer(v.GWindow))))
|
||||
}
|
520
vendor/github.com/mattn/go-gtk/gdkpixbuf/gdkpixbuf.go
generated
vendored
Normal file
520
vendor/github.com/mattn/go-gtk/gdkpixbuf/gdkpixbuf.go
generated
vendored
Normal file
@ -0,0 +1,520 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gdkpixbuf
|
||||
|
||||
// #include "gdkpixbuf.go.h"
|
||||
// #cgo pkg-config: gdk-pixbuf-2.0
|
||||
import "C"
|
||||
import "github.com/mattn/go-gtk/glib"
|
||||
import (
|
||||
"log"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func gstring(s *C.char) *C.gchar { return C.toGstr(s) }
|
||||
func cstring(s *C.gchar) *C.char { return C.toCstr(s) }
|
||||
func gostring(s *C.gchar) string { return C.GoString(cstring(s)) }
|
||||
|
||||
func gbool(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func gobool(b C.gboolean) bool {
|
||||
if b != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func cfree(s *C.char) { C.freeCstr(s) }
|
||||
|
||||
func panic_if_version_older(major int, minor int, micro int, function string) {
|
||||
if C._check_version(C.int(major), C.int(minor), C.int(micro)) == 0 {
|
||||
log.Panicf("%s is not provided on your Glib, version %d.%d is required\n", function, major, minor)
|
||||
}
|
||||
}
|
||||
|
||||
func panic_if_version_older_auto(major, minor, micro int) {
|
||||
if C._check_version(C.int(major), C.int(minor), C.int(micro)) != 0 {
|
||||
return
|
||||
}
|
||||
formatStr := "%s is not provided on your Glib, version %d.%d is required\n"
|
||||
if pc, _, _, ok := runtime.Caller(1); ok {
|
||||
log.Panicf(formatStr, runtime.FuncForPC(pc).Name(), major, minor)
|
||||
} else {
|
||||
log.Panicf("Glib version %d.%d is required (unknown caller, see stack)\n",
|
||||
major, minor)
|
||||
}
|
||||
}
|
||||
|
||||
func deprecated_since(major int, minor int, micro int, function string) {
|
||||
if C._check_version(C.int(major), C.int(minor), C.int(micro)) != 0 {
|
||||
log.Printf("\nWarning: %s is deprecated since glib %d.%d\n", function, major, minor)
|
||||
}
|
||||
}
|
||||
|
||||
func argumentPanic(message string) {
|
||||
if pc, _, _, ok := runtime.Caller(2); ok {
|
||||
log.Panicf("Arguments error: %s : %s\n",
|
||||
runtime.FuncForPC(pc).Name(), message)
|
||||
} else {
|
||||
log.Panicln("Arguments error: (unknown caller, see stack):", message)
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Pixbuf
|
||||
//-----------------------------------------------------------------------
|
||||
type Pixbuf struct {
|
||||
*GdkPixbuf
|
||||
*glib.GObject
|
||||
}
|
||||
|
||||
type GdkPixbuf struct {
|
||||
GPixbuf *C.GdkPixbuf
|
||||
}
|
||||
|
||||
func NewGdkPixbuf(p unsafe.Pointer) *GdkPixbuf {
|
||||
return &GdkPixbuf{(*C.GdkPixbuf)(p)}
|
||||
}
|
||||
|
||||
// File Loading
|
||||
// GdkPixbuf * gdk_pixbuf_new (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height);
|
||||
func NewPixbuf(colorspace Colorspace, hasAlpha bool, bitsPerSample, width, height int) *Pixbuf {
|
||||
gpixbuf := C.gdk_pixbuf_new(
|
||||
C.GdkColorspace(colorspace),
|
||||
gbool(hasAlpha),
|
||||
C.int(bitsPerSample),
|
||||
C.int(width),
|
||||
C.int(height),
|
||||
)
|
||||
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPixbufFromFile(filename string) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
ptr := C.CString(filename)
|
||||
defer cfree(ptr)
|
||||
gpixbuf := C.gdk_pixbuf_new_from_file(ptr, &err)
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewPixbufFromFileAtSize(filename string, width, heigth int) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
ptr := C.CString(filename)
|
||||
defer cfree(ptr)
|
||||
gpixbuf := C.gdk_pixbuf_new_from_file_at_size(ptr, C.int(width), C.int(heigth), &err)
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewPixbufFromFileAtScale(filename string, width, height int, preserve_aspect_ratio bool) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
ptr := C.CString(filename)
|
||||
defer cfree(ptr)
|
||||
gpixbuf := C.gdk_pixbuf_new_from_file_at_scale(ptr, C.int(width), C.int(height), gbool(preserve_aspect_ratio), &err)
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPixbufFromData creates a Pixbuf from image data in a byte array
|
||||
//
|
||||
// Can be used for reading Base64 encoded images easily with the output from base64.StdEncoding.DecodeString("...")
|
||||
func NewPixbufFromData(buffer []byte) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
loader := C.gdk_pixbuf_loader_new()
|
||||
C.gdk_pixbuf_loader_write(loader, C.to_gucharptr(unsafe.Pointer(&buffer[0])), C.gsize(len(buffer)), &err)
|
||||
gpixbuf := C.gdk_pixbuf_loader_get_pixbuf(loader)
|
||||
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPixbufFromBytes creates a Pixbuf from image data in a byte array
|
||||
//
|
||||
// Can be used for reading Base64 encoded images easily with the output from base64.StdEncoding.DecodeString("...")
|
||||
func NewPixbufFromBytes(buffer []byte) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
loader := C.gdk_pixbuf_loader_new()
|
||||
C.gdk_pixbuf_loader_write(loader, C.to_gucharptr(unsafe.Pointer(&buffer[0])), C.gsize(len(buffer)), &err)
|
||||
gpixbuf := C.gdk_pixbuf_loader_get_pixbuf(loader)
|
||||
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewPixbufFromXpmData(data **byte) (*Pixbuf, *glib.Error) {
|
||||
var err *C.GError
|
||||
gpixbuf := C.gdk_pixbuf_new_from_xpm_data(
|
||||
(**C.char)(unsafe.Pointer(data)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetType() int {
|
||||
return int(C.gdk_pixbuf_get_type())
|
||||
}
|
||||
|
||||
func GetFileInfo(filename string, width, height *int) *Format {
|
||||
ptr := C.CString(filename)
|
||||
defer cfree(ptr)
|
||||
|
||||
var w, h C.gint
|
||||
format := &Format{C.gdk_pixbuf_get_file_info(gstring(ptr), &w, &h)}
|
||||
*width = int(w)
|
||||
*height = int(h)
|
||||
return format
|
||||
}
|
||||
|
||||
// Scaling
|
||||
|
||||
type InterpType int
|
||||
|
||||
const (
|
||||
INTERP_NEAREST InterpType = iota
|
||||
INTERP_TILES
|
||||
INTERP_BILINEAR
|
||||
INTERP_HYPER
|
||||
)
|
||||
|
||||
func (p *Pixbuf) ScaleSimple(width, height int, interp InterpType) *Pixbuf {
|
||||
gpixbuf := C.gdk_pixbuf_scale_simple(p.GPixbuf, C.int(width), C.int(height), C.GdkInterpType(interp))
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pixbuf) Scale(x, y, width, height int, offsetX, offsetY, scaleX, scaleY float64, interp InterpType) *Pixbuf {
|
||||
var gpixbuf *C.GdkPixbuf
|
||||
C.gdk_pixbuf_scale(
|
||||
p.GPixbuf,
|
||||
gpixbuf,
|
||||
C.int(x), C.int(y),
|
||||
C.int(width), C.int(height),
|
||||
C.double(offsetX), C.double(offsetY),
|
||||
C.double(scaleX), C.double(scaleY),
|
||||
C.GdkInterpType(interp))
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
// gdk_pixbuf_composite_color_simple
|
||||
// gdk_pixbuf_composite
|
||||
// gdk_pixbuf_composite_color
|
||||
|
||||
type PixbufRotation int
|
||||
|
||||
const (
|
||||
PIXBUF_ROTATE_NONE PixbufRotation = 0
|
||||
PIXBUF_ROTATE_COUNTERCLOCKWISE PixbufRotation = 90
|
||||
PIXBUF_ROTATE_UPSIDEDOWN PixbufRotation = 180
|
||||
PIXBUF_ROTATE_CLOCKWISE PixbufRotation = 270
|
||||
)
|
||||
|
||||
func (p *Pixbuf) RotateSimple(angle PixbufRotation) *Pixbuf {
|
||||
gpixbuf := C.gdk_pixbuf_rotate_simple(p.GPixbuf, C.GdkPixbufRotation(angle))
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pixbuf) Flip(horizontal bool) *Pixbuf {
|
||||
gpixbuf := C.gdk_pixbuf_flip(p.GPixbuf, gbool(horizontal))
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pixbuf) Fill(pixel uint32) {
|
||||
C.gdk_pixbuf_fill(p.GPixbuf, C.guint32(pixel))
|
||||
}
|
||||
|
||||
// The GdkPixbuf Structure
|
||||
|
||||
type Colorspace int
|
||||
|
||||
const (
|
||||
GDK_COLORSPACE_RGB Colorspace = iota
|
||||
)
|
||||
|
||||
type PixbufAlphaMode int
|
||||
|
||||
const (
|
||||
GDK_PIXBUF_ALPHA_BILEVEL PixbufAlphaMode = iota
|
||||
GDK_PIXBUF_ALPHA_FULL
|
||||
)
|
||||
|
||||
func (p *Pixbuf) GetColorspace() Colorspace {
|
||||
return Colorspace(C.gdk_pixbuf_get_colorspace(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetNChannels() int {
|
||||
return int(C.gdk_pixbuf_get_n_channels(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetHasAlpha() bool {
|
||||
return gobool(C.gdk_pixbuf_get_has_alpha(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetBitsPerSample() int {
|
||||
return int(C.gdk_pixbuf_get_bits_per_sample(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetPixels() []byte {
|
||||
ptr := C.gdk_pixbuf_get_pixels(
|
||||
p.GPixbuf,
|
||||
)
|
||||
return (*[1 << 30]byte)(unsafe.Pointer(ptr))[:]
|
||||
}
|
||||
|
||||
// guchar * gdk_pixbuf_get_pixels_with_length (const GdkPixbuf *pixbuf, guint *length);
|
||||
//
|
||||
// Retuns a slice of byte backed by a C array of pixbuf data.
|
||||
func (p *Pixbuf) GetPixelsWithLength() []byte {
|
||||
panic_if_version_older(2, 26, 0, "gdk_pixbuf_get_pixels_with_length()")
|
||||
length := C.guint(0)
|
||||
ptr := C._gdk_pixbuf_get_pixels_with_length(
|
||||
p.GPixbuf,
|
||||
&length,
|
||||
)
|
||||
return (*[1 << 30]byte)(unsafe.Pointer(ptr))[:length]
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetWidth() int {
|
||||
return int(C.gdk_pixbuf_get_width(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetHeight() int {
|
||||
return int(C.gdk_pixbuf_get_height(p.GPixbuf))
|
||||
}
|
||||
|
||||
func (p *Pixbuf) GetRowstride() int {
|
||||
return int(C.gdk_pixbuf_get_rowstride(p.GPixbuf))
|
||||
}
|
||||
|
||||
// gdk_pixbuf_get_byte_length
|
||||
// gdk_pixbuf_get_option
|
||||
|
||||
// File saving
|
||||
|
||||
func (p *Pixbuf) Save(filename, savetype string, options ...string) *glib.Error {
|
||||
if len(options)%2 != 0 {
|
||||
argumentPanic("Save options must be even (key and value)")
|
||||
}
|
||||
|
||||
pfilename := C.CString(filename)
|
||||
defer cfree(pfilename)
|
||||
psavetype := C.CString(savetype)
|
||||
defer cfree(psavetype)
|
||||
|
||||
klen := len(options) / 2
|
||||
keys := C.makeCstrv(C.int(klen + 1))
|
||||
vals := C.makeCstrv(C.int(klen + 1))
|
||||
for i := 0; i < klen; i++ {
|
||||
C.setCstr(keys, C.int(i), C.CString(options[2*i]))
|
||||
C.setCstr(vals, C.int(i), C.CString(options[2*i+1]))
|
||||
}
|
||||
C.setCstr(keys, C.int(klen), nil)
|
||||
C.setCstr(vals, C.int(klen), nil)
|
||||
defer func() {
|
||||
for i := 0; i < klen; i++ {
|
||||
cfree(C.getCstr(keys, C.int(i)))
|
||||
cfree(C.getCstr(vals, C.int(i)))
|
||||
}
|
||||
C.freeCstrv(keys)
|
||||
C.freeCstrv(vals)
|
||||
}()
|
||||
|
||||
var err *C.GError
|
||||
C.gdk_pixbuf_savev(p.GPixbuf, pfilename, psavetype, keys, vals, &err)
|
||||
if err != nil {
|
||||
return glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Animation
|
||||
//-----------------------------------------------------------------------
|
||||
type Animation struct {
|
||||
GPixbufAnimation *C.GdkPixbufAnimation
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Format
|
||||
//-----------------------------------------------------------------------
|
||||
type Format struct {
|
||||
GPixbufFormat *C.GdkPixbufFormat
|
||||
}
|
||||
|
||||
// gdk_pixbuf_get_formats
|
||||
|
||||
func (v *Format) GetName() string {
|
||||
return gostring(C.gdk_pixbuf_format_get_name(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
func (v *Format) GetDescription() string {
|
||||
return gostring(C.gdk_pixbuf_format_get_description(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
func (v *Format) GetMimeTypes() []string {
|
||||
gstrv := C.gdk_pixbuf_format_get_mime_types(v.GPixbufFormat)
|
||||
defer C.g_strfreev(gstrv)
|
||||
s := make([]string, 0)
|
||||
for i := 0; C.getGstr(gstrv, C.int(i)) != nil; i++ {
|
||||
s = append(s, gostring(C.getGstr(gstrv, C.int(i))))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (v *Format) GetExtensions() []string {
|
||||
gstrv := C.gdk_pixbuf_format_get_extensions(v.GPixbufFormat)
|
||||
defer C.g_strfreev(gstrv)
|
||||
s := make([]string, 0)
|
||||
for i := 0; C.getGstr(gstrv, C.int(i)) != nil; i++ {
|
||||
s = append(s, gostring(C.getGstr(gstrv, C.int(i))))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (v *Format) IsWritable() bool {
|
||||
return gobool(C.gdk_pixbuf_format_is_writable(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
func (v *Format) IsScalable() bool {
|
||||
return gobool(C.gdk_pixbuf_format_is_scalable(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
func (v *Format) IsDisabled() bool {
|
||||
return gobool(C.gdk_pixbuf_format_is_disabled(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
func (v *Format) SetDisabled(disabled bool) {
|
||||
C.gdk_pixbuf_format_set_disabled(v.GPixbufFormat, gbool(disabled))
|
||||
}
|
||||
|
||||
func (v *Format) GetLicense() string {
|
||||
return gostring(C.gdk_pixbuf_format_get_license(v.GPixbufFormat))
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Loader
|
||||
//-----------------------------------------------------------------------
|
||||
type Loader struct {
|
||||
GPixbufLoader *C.GdkPixbufLoader
|
||||
}
|
||||
|
||||
func NewLoader() *Loader {
|
||||
return &Loader{
|
||||
C.gdk_pixbuf_loader_new()}
|
||||
}
|
||||
|
||||
func NewLoaderWithType(image_type string) (loader *Loader, err *glib.Error) {
|
||||
var gerr *C.GError
|
||||
ptr := C.CString(image_type)
|
||||
defer cfree(ptr)
|
||||
loader = &Loader{
|
||||
C.gdk_pixbuf_loader_new_with_type(ptr, &gerr)}
|
||||
if gerr != nil {
|
||||
err = glib.ErrorFromNative(unsafe.Pointer(gerr))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NewLoaderWithMimeType(mime_type string) (loader *Loader, err *glib.Error) {
|
||||
var error *C.GError
|
||||
ptr := C.CString(mime_type)
|
||||
defer cfree(ptr)
|
||||
loader = &Loader{
|
||||
C.gdk_pixbuf_loader_new_with_mime_type(ptr, &error)}
|
||||
err = glib.ErrorFromNative(unsafe.Pointer(error))
|
||||
return
|
||||
}
|
||||
|
||||
func (v Loader) GetPixbuf() *Pixbuf {
|
||||
gpixbuf := C.gdk_pixbuf_loader_get_pixbuf(v.GPixbufLoader)
|
||||
return &Pixbuf{
|
||||
GdkPixbuf: &GdkPixbuf{gpixbuf},
|
||||
GObject: glib.ObjectFromNative(unsafe.Pointer(gpixbuf)),
|
||||
}
|
||||
}
|
||||
|
||||
func (v Loader) Write(buf []byte) (bool, *glib.Error) {
|
||||
var err *C.GError
|
||||
var pbuf *byte
|
||||
pbuf = &buf[0]
|
||||
ret := gobool(C.gdk_pixbuf_loader_write(v.GPixbufLoader, C.to_gucharptr(unsafe.Pointer(pbuf)), C.gsize(len(buf)), &err))
|
||||
if err != nil {
|
||||
return ret, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (v Loader) Close() (bool, *glib.Error) {
|
||||
var err *C.GError
|
||||
ret := gobool(C.gdk_pixbuf_loader_close(v.GPixbufLoader, &err))
|
||||
if err != nil {
|
||||
return ret, glib.ErrorFromNative(unsafe.Pointer(err))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
//func (v Loader) GetPixbufAnimation() *Animation {
|
||||
// return &Animation {
|
||||
// C.gdk_pixbuf_loader_get_animation(v.GPixbufLoader) };
|
||||
//}
|
||||
func (v Loader) SetSize(width int, height int) {
|
||||
C.gdk_pixbuf_loader_set_size(v.GPixbufLoader, C.int(width), C.int(height))
|
||||
}
|
||||
|
||||
func (v Loader) GetFormat() *Format {
|
||||
return &Format{
|
||||
C.gdk_pixbuf_loader_get_format(v.GPixbufLoader)}
|
||||
}
|
||||
|
||||
// FINISH
|
48
vendor/github.com/mattn/go-gtk/gdkpixbuf/gdkpixbuf.go.h
generated
vendored
Normal file
48
vendor/github.com/mattn/go-gtk/gdkpixbuf/gdkpixbuf.go.h
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef GO_GDK_PIXBUF_H
|
||||
#define GO_GDK_PIXBUF_H
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
//static const gchar* to_gcharptr(const char* s) { return (const gchar*)s; }
|
||||
static guchar* to_gucharptr(void* s) { return (guchar*)s; }
|
||||
|
||||
static inline GdkPixbuf* toGdkPixbuf(void* p) { return GDK_PIXBUF(p); }
|
||||
|
||||
static inline gchar* toGstr(const char* s) { return (gchar*)s; }
|
||||
static inline char* toCstr(const gchar* s) { return (char*)s; }
|
||||
|
||||
static inline void freeCstr(char* s) { free(s); }
|
||||
|
||||
static inline char** makeCstrv(int count) {
|
||||
return (char**)malloc(sizeof(char*) * count);
|
||||
}
|
||||
|
||||
static guchar* _gdk_pixbuf_get_pixels_with_length(const GdkPixbuf *pixbuf, guint *length) {
|
||||
#if GDK_PIXBUF_MAJOR >= 2 && GDK_PIXBUF_MINOR >= 26
|
||||
return gdk_pixbuf_get_pixels_with_length(pixbuf, length);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
static inline void freeCstrv(char** cstrv) { free(cstrv); }
|
||||
static inline char* getCstr(char** cstrv, int n) { return cstrv[n]; }
|
||||
static inline void setCstr(char** cstrv, int n, char* str) { cstrv[n] = str; }
|
||||
static inline gchar* getGstr(gchar** gstrv, int n) { return gstrv[n]; }
|
||||
|
||||
static int _check_version(int major, int minor, int micro) {
|
||||
if (GDK_PIXBUF_MAJOR > major) return 1;
|
||||
if (GDK_PIXBUF_MAJOR < major) return 0;
|
||||
if (GDK_PIXBUF_MINOR > minor) return 1;
|
||||
if (GDK_PIXBUF_MINOR < minor) return 0;
|
||||
if (GDK_PIXBUF_MICRO > micro) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
1052
vendor/github.com/mattn/go-gtk/glib/glib.go
generated
vendored
Normal file
1052
vendor/github.com/mattn/go-gtk/glib/glib.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
218
vendor/github.com/mattn/go-gtk/glib/glib.go.h
generated
vendored
Normal file
218
vendor/github.com/mattn/go-gtk/glib/glib.go.h
generated
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
#ifndef GO_GLIB_H
|
||||
#define GO_GLIB_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
static GList* to_list(void* l) {
|
||||
return (GList*)l;
|
||||
}
|
||||
static GSList* to_slist(void* sl) {
|
||||
return (GSList*)sl;
|
||||
}
|
||||
static GError* to_error(void* err) {
|
||||
return (GError*)err;
|
||||
}
|
||||
static inline GObject* to_GObject(void* o) { return G_OBJECT(o); }
|
||||
|
||||
static inline gchar* to_gcharptr(const char* s) { return (gchar*)s; }
|
||||
|
||||
static inline char* to_charptr(const gchar* s) { return (char*)s; }
|
||||
|
||||
static inline char* to_charptr_from_gpointer(gpointer s) { return (char*)s; }
|
||||
|
||||
static inline char* to_charptr_voidp(const void* s) { return (char*)s; }
|
||||
|
||||
static inline void free_string(char* s) { free(s); }
|
||||
|
||||
static inline gchar* next_string(gchar* s) { return (gchar*)(s + strlen(s) + 1); }
|
||||
|
||||
static gboolean _g_utf8_validate(void* str, int len, void* ppbar) {
|
||||
return g_utf8_validate((const gchar*)str, (gssize)len, (const gchar**)ppbar);
|
||||
}
|
||||
|
||||
static gchar* _g_locale_to_utf8(void* opsysstring, int len, int* bytes_read, int* bytes_written, GError** error) {
|
||||
return g_locale_from_utf8((const gchar*)opsysstring, (gssize)len, (gsize*)bytes_read, (gsize*)bytes_written, error);
|
||||
}
|
||||
|
||||
static gchar* _g_locale_from_utf8(char* utf8string, int len, int* bytes_read, int* bytes_written, GError** error) {
|
||||
return g_locale_from_utf8((const gchar*)utf8string, (gssize)len, (gsize*)bytes_read, (gsize*)bytes_written, error);
|
||||
}
|
||||
static void _g_object_set_ptr(gpointer object, const gchar *property_name, void* value) {
|
||||
g_object_set(object, property_name, value, NULL);
|
||||
}
|
||||
static void _g_object_set_addr(gpointer object, const gchar *property_name, void* value) {
|
||||
g_object_set(object, property_name, *(gpointer**)value, NULL);
|
||||
}
|
||||
//static void _g_object_get(gpointer object, const gchar *property_name, void* value) {
|
||||
// g_object_get(object, property_name, value, NULL);
|
||||
//}
|
||||
|
||||
static void g_value_init_int(GValue* gv) { g_value_init(gv, G_TYPE_INT); }
|
||||
static void g_value_init_string(GValue* gv) { g_value_init(gv, G_TYPE_STRING); }
|
||||
|
||||
static GValue* init_gvalue_string_type() {
|
||||
GValue* gv = g_new0(GValue, 1);
|
||||
g_value_init(gv, G_TYPE_STRING);
|
||||
return gv;
|
||||
}
|
||||
static GValue* init_gvalue_string(gchar* val) {
|
||||
GValue* gv = init_gvalue_string_type();
|
||||
g_value_set_string(gv, val);
|
||||
return gv;
|
||||
}
|
||||
|
||||
static GValue* init_gvalue_int_type() {
|
||||
GValue* gv = g_new0(GValue, 1);
|
||||
g_value_init(gv, G_TYPE_INT);
|
||||
return gv;
|
||||
}
|
||||
static GValue* init_gvalue_int(gint val) {
|
||||
GValue* gv = init_gvalue_int_type();
|
||||
g_value_set_int(gv, val);
|
||||
return gv;
|
||||
}
|
||||
|
||||
static GValue* init_gvalue_uint(guint val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_UINT); g_value_set_uint(gv, val); return gv; }
|
||||
static GValue* init_gvalue_int64(gint64 val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_INT64); g_value_set_int64(gv, val); return gv; }
|
||||
static GValue* init_gvalue_double(gdouble val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_DOUBLE); g_value_set_double(gv, val); return gv; }
|
||||
static GValue* init_gvalue_byte(guchar val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_UCHAR); g_value_set_uchar(gv, val); return gv; }
|
||||
static GValue* init_gvalue_bool(gboolean val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_BOOLEAN); g_value_set_boolean(gv, val); return gv; }
|
||||
//static GValue* init_gvalue_pointer(gpointer val) { GValue* gv = g_new0(GValue, 1); g_value_init(gv, G_TYPE_POINTER); g_value_set_pointer(gv, val); return gv; }
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int func_no;
|
||||
void* target;
|
||||
uintptr_t* args;
|
||||
int args_no;
|
||||
void* ret;
|
||||
gulong id;
|
||||
} callback_info;
|
||||
|
||||
static uintptr_t callback_info_get_arg(callback_info* cbi, int idx) {
|
||||
return cbi->args[idx];
|
||||
}
|
||||
extern void _go_glib_callback(callback_info* cbi);
|
||||
static uintptr_t _glib_callback(void *data, ...) {
|
||||
va_list ap;
|
||||
callback_info *cbi = (callback_info*) data;
|
||||
|
||||
int i;
|
||||
cbi->args = (uintptr_t*)malloc(sizeof(uintptr_t)*cbi->args_no);
|
||||
va_start(ap, data);
|
||||
for (i = 0; i < cbi->args_no; i++) {
|
||||
cbi->args[i] = va_arg(ap, uintptr_t);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
_go_glib_callback(cbi);
|
||||
|
||||
free(cbi->args);
|
||||
|
||||
return *(uintptr_t*)(&cbi->ret);
|
||||
}
|
||||
|
||||
static void free_callback_info(gpointer data, GClosure *closure) {
|
||||
g_slice_free(callback_info, data);
|
||||
}
|
||||
|
||||
static callback_info* _g_signal_connect(void* obj, gchar* name, int func_no, int flags) {
|
||||
GSignalQuery query;
|
||||
callback_info* cbi;
|
||||
guint signal_id = g_signal_lookup(name, G_OBJECT_TYPE(obj));
|
||||
g_signal_query(signal_id, &query);
|
||||
cbi = g_slice_new0(callback_info);
|
||||
cbi->name = g_strdup(name);
|
||||
cbi->func_no = func_no;
|
||||
cbi->args = NULL;
|
||||
cbi->target = obj;
|
||||
cbi->args_no = query.n_params;
|
||||
if (((GConnectFlags)flags) == G_CONNECT_AFTER)
|
||||
cbi->id = g_signal_connect_data((gpointer)obj, name, G_CALLBACK(_glib_callback), (gpointer)cbi, free_callback_info, G_CONNECT_AFTER);
|
||||
else
|
||||
cbi->id = g_signal_connect_data((gpointer)obj, name, G_CALLBACK(_glib_callback), (gpointer)cbi, free_callback_info, G_CONNECT_SWAPPED);
|
||||
return cbi;
|
||||
}
|
||||
|
||||
static void _g_signal_emit_by_name(gpointer instance, const gchar *detailed_signal) {
|
||||
g_signal_emit_by_name(instance, detailed_signal);
|
||||
}
|
||||
|
||||
static gulong _g_signal_callback_id(callback_info* cbi) {
|
||||
return cbi->id;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int func_no;
|
||||
gboolean ret;
|
||||
guint id;
|
||||
} sourcefunc_info;
|
||||
|
||||
extern void _go_glib_sourcefunc(sourcefunc_info* sfi);
|
||||
static gboolean _go_sourcefunc(void *data) {
|
||||
sourcefunc_info *sfi = (sourcefunc_info*) data;
|
||||
|
||||
_go_glib_sourcefunc(sfi);
|
||||
|
||||
return sfi->ret;
|
||||
}
|
||||
|
||||
static void free_sourcefunc_info(gpointer data) {
|
||||
g_slice_free(sourcefunc_info, data);
|
||||
}
|
||||
|
||||
static sourcefunc_info* _g_idle_add(int func_no) {
|
||||
sourcefunc_info* sfi;
|
||||
sfi = g_slice_new0(sourcefunc_info);
|
||||
sfi->func_no = func_no;
|
||||
sfi->id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, _go_sourcefunc, sfi, free_sourcefunc_info);
|
||||
return sfi;
|
||||
}
|
||||
|
||||
static sourcefunc_info* _g_timeout_add(guint interval, int func_no) {
|
||||
sourcefunc_info* sfi;
|
||||
sfi = g_slice_new0(sourcefunc_info);
|
||||
sfi->func_no = func_no;
|
||||
sfi->id = g_timeout_add_full(G_PRIORITY_DEFAULT, interval, _go_sourcefunc, sfi, free_sourcefunc_info);
|
||||
return sfi;
|
||||
}
|
||||
|
||||
static void _g_thread_init(GThreadFunctions *vtable) {
|
||||
#if !GLIB_CHECK_VERSION(2,32,0)
|
||||
#ifdef G_THREADS_ENABLED
|
||||
g_thread_init(vtable);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,28,0)
|
||||
static const gchar *
|
||||
g_get_user_runtime_dir (void)
|
||||
{
|
||||
#ifndef G_OS_WIN32
|
||||
static const gchar *runtime_dir;
|
||||
static gsize initialised;
|
||||
|
||||
if (g_once_init_enter (&initialised)) {
|
||||
runtime_dir = g_strdup (getenv ("XDG_RUNTIME_DIR"));
|
||||
if (runtime_dir == NULL)
|
||||
g_warning ("XDG_RUNTIME_DIR variable not set. Falling back to XDG cache dir.");
|
||||
g_once_init_leave (&initialised, 1);
|
||||
}
|
||||
|
||||
if (runtime_dir)
|
||||
return runtime_dir;
|
||||
|
||||
/* Both fallback for UNIX and the default
|
||||
* in Windows: use the user cache directory.
|
||||
*/
|
||||
#endif
|
||||
|
||||
return g_get_user_cache_dir ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
11272
vendor/github.com/mattn/go-gtk/gtk/gtk.go
generated
vendored
Normal file
11272
vendor/github.com/mattn/go-gtk/gtk/gtk.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
873
vendor/github.com/mattn/go-gtk/gtk/gtk.go.h
generated
vendored
Normal file
873
vendor/github.com/mattn/go-gtk/gtk/gtk.go.h
generated
vendored
Normal file
@ -0,0 +1,873 @@
|
||||
#ifndef GO_GTK_H
|
||||
#define GO_GTK_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
//Why is this necessary?
|
||||
//#include <gdk/gdkx.h>
|
||||
//#include <gdk/gdkquartz.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static void _gtk_init(int* argc, char*** argv) {
|
||||
gtk_init((int*)argc, (char***)argv);
|
||||
}
|
||||
|
||||
static GtkClipboard* _gtk_clipboard_get_for_display(void* display, void* selection) {
|
||||
return gtk_clipboard_get_for_display((GdkDisplay*)display, (GdkAtom)selection);
|
||||
}
|
||||
|
||||
static int _gtk_selection_data_get_length(void* selection_data) {
|
||||
return (int) gtk_selection_data_get_length((GtkSelectionData*)selection_data);
|
||||
}
|
||||
|
||||
static void* _gtk_selection_data_get_data(void* selection_data) {
|
||||
return (char*) gtk_selection_data_get_data((GtkSelectionData*)selection_data);
|
||||
}
|
||||
|
||||
static char* _gtk_selection_data_get_text(void* selection_data) {
|
||||
return (char*) gtk_selection_data_get_text((GtkSelectionData*)selection_data);
|
||||
}
|
||||
|
||||
static void _gtk_drag_finish(void *context, gboolean success, gboolean del, guint32 time_) {
|
||||
gtk_drag_finish((GdkDragContext*) context, success, del, time_);
|
||||
}
|
||||
|
||||
static GtkWidget* _gtk_message_dialog_new(GtkWidget* parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, gchar *message) {
|
||||
return gtk_message_dialog_new(
|
||||
GTK_WINDOW(parent),
|
||||
flags,
|
||||
type,
|
||||
buttons,
|
||||
message, NULL);
|
||||
}
|
||||
|
||||
static GtkWidget* _gtk_message_dialog_new_with_markup(GtkWidget* parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, gchar *message) {
|
||||
return gtk_message_dialog_new_with_markup(
|
||||
GTK_WINDOW(parent),
|
||||
flags,
|
||||
type,
|
||||
buttons,
|
||||
message, NULL);
|
||||
}
|
||||
|
||||
static GtkWidget* _gtk_file_chooser_dialog_new(const gchar* title,
|
||||
GtkWidget* parent, int file_chooser_action, int action, const gchar* button) {
|
||||
return gtk_file_chooser_dialog_new(
|
||||
title,
|
||||
GTK_WINDOW(parent),
|
||||
file_chooser_action,
|
||||
button,
|
||||
action,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GtkWidget* _gtk_file_chooser_widget_new(int file_chooser_action) {
|
||||
return gtk_file_chooser_widget_new(file_chooser_action);
|
||||
}
|
||||
|
||||
static GtkTreePath* _gtk_tree_model_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter) {
|
||||
return gtk_tree_model_get_path(tree_model, iter);
|
||||
}
|
||||
|
||||
static void _gtk_text_buffer_insert_with_tag(GtkTextBuffer* buffer, GtkTextIter* iter, const gchar* text, gint len, GtkTextTag* tag) {
|
||||
gtk_text_buffer_insert_with_tags(buffer, iter, text, len, tag, NULL);
|
||||
}
|
||||
|
||||
//static void _gtk_text_buffer_insert_with_tags_by_name(GtkTextBuffer* buffer, GtkTextIter* iter, const gchar* text, gint len, const gchar* first_tag_name, ...);
|
||||
|
||||
static GtkTextTag* _gtk_text_buffer_create_tag(GtkTextBuffer* buffer, const gchar* tag_name) {
|
||||
return gtk_text_buffer_create_tag(buffer, tag_name, NULL);
|
||||
}
|
||||
|
||||
static void _gtk_widget_hide_on_delete(GtkWidget* w) {
|
||||
g_signal_connect(GTK_WIDGET(w), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||
}
|
||||
|
||||
static void _gtk_text_iter_assign(GtkTextIter* one, GtkTextIter* two) {
|
||||
*one = *two;
|
||||
}
|
||||
|
||||
static void _apply_property(void* obj, const gchar* prop, const gchar* val) {
|
||||
GParamSpec *pspec;
|
||||
GValue fromvalue = { 0, };
|
||||
GValue tovalue = { 0, };
|
||||
pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), prop);
|
||||
if (!pspec) return;
|
||||
g_value_init(&fromvalue, G_TYPE_STRING);
|
||||
g_value_set_string(&fromvalue, val);
|
||||
g_value_init(&tovalue, G_PARAM_SPEC_VALUE_TYPE(pspec));
|
||||
g_value_transform(&fromvalue, &tovalue);
|
||||
g_object_set_property((GObject *)obj, prop, &tovalue);
|
||||
g_value_unset(&fromvalue);
|
||||
g_value_unset(&tovalue);
|
||||
}
|
||||
|
||||
static GtkTreeViewColumn* _gtk_tree_view_column_new_with_attribute(gchar* title, GtkCellRenderer* cell) {
|
||||
return gtk_tree_view_column_new_with_attributes(title, cell, NULL);
|
||||
}
|
||||
|
||||
static GtkTreeViewColumn* _gtk_tree_view_column_new_with_attributes(gchar* title, GtkCellRenderer* cell, gchar* prop, gint column) {
|
||||
return gtk_tree_view_column_new_with_attributes(title, cell, prop, column, NULL);
|
||||
}
|
||||
|
||||
static void _gtk_list_store_set_ptr(GtkListStore* list_store, GtkTreeIter* iter, gint column, void* data) {
|
||||
gtk_list_store_set(list_store, iter, column, data, -1);
|
||||
}
|
||||
|
||||
static void _gtk_list_store_set_addr(GtkListStore* list_store, GtkTreeIter* iter, gint column, void* data) {
|
||||
gtk_list_store_set(list_store, iter, column, *(gpointer*)data, -1);
|
||||
}
|
||||
|
||||
static void _gtk_tree_store_set_ptr(GtkTreeStore* tree_store, GtkTreeIter* iter, gint column, void* data) {
|
||||
gtk_tree_store_set(tree_store, iter, column, data, -1);
|
||||
}
|
||||
|
||||
static void _gtk_tree_store_set_addr(GtkTreeStore* tree_store, GtkTreeIter* iter, gint column, void* data) {
|
||||
gtk_tree_store_set(tree_store, iter, column, *(gpointer*)data, -1);
|
||||
}
|
||||
|
||||
//static void _gtk_range_get_value(GtkRange* range, gdouble* value) {
|
||||
// *value = gtk_range_get_value(range);
|
||||
//}
|
||||
|
||||
static GtkTreeIter* _gtk_tree_iter_new() {
|
||||
return (GtkTreeIter*)malloc(sizeof(GtkTreeIter));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkTreeModel* model;
|
||||
GtkTreeIter* a;
|
||||
GtkTreeIter* b;
|
||||
gint columnNum;
|
||||
void* gots;
|
||||
int ret;
|
||||
} _gtk_sort_func_info;
|
||||
|
||||
extern void _go_call_sort_func(_gtk_sort_func_info* gsfi);
|
||||
static gint sortable_sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer gsfi) {
|
||||
gint gret = 0;
|
||||
_gtk_sort_func_info* gsfil = (_gtk_sort_func_info*) gsfi;
|
||||
gsfil->model = model;
|
||||
gsfil->a = a;
|
||||
gsfil->b = b;
|
||||
_go_call_sort_func(gsfil);
|
||||
gret = gsfil->ret;
|
||||
return gret;
|
||||
}
|
||||
|
||||
static void free_sort_func(gpointer gsfi) {
|
||||
free(gsfi);
|
||||
}
|
||||
|
||||
static void _gtk_tree_sortable_set_sort_func(GtkTreeSortable* ts, gint col, void* gots) {
|
||||
_gtk_sort_func_info* gsfi = malloc(sizeof(_gtk_sort_func_info));
|
||||
gsfi->columnNum = col;
|
||||
gsfi->gots = gots;
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ts), col, sortable_sort_func, (gpointer) gsfi, free_sort_func);
|
||||
}
|
||||
|
||||
extern void _go_gtk_builder_connect_signals_full_cb(void* builder, void* object, gchar *signal_name, gchar *handler_name, void* connect_object, int flags, void* user_data);
|
||||
static void _gtk_builder_connect_signals_full(GtkBuilder *builder, void* user_data) {
|
||||
gtk_builder_connect_signals_full(builder, (GtkBuilderConnectFunc)_go_gtk_builder_connect_signals_full_cb, user_data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkMenu *menu;
|
||||
gint x;
|
||||
gint y;
|
||||
gboolean push_in;
|
||||
gpointer data;
|
||||
} _gtk_menu_position_func_info;
|
||||
|
||||
extern void _go_gtk_menu_position_func(_gtk_menu_position_func_info* gmpfi);
|
||||
static void _c_gtk_menu_position_func(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) {
|
||||
_gtk_menu_position_func_info gmpfi;
|
||||
gmpfi.menu = menu;
|
||||
gmpfi.x = *x;
|
||||
gmpfi.y = *y;
|
||||
gmpfi.push_in = *push_in;
|
||||
gmpfi.data = user_data;
|
||||
_go_gtk_menu_position_func(&gmpfi);
|
||||
*x = gmpfi.x;
|
||||
*y = gmpfi.y;
|
||||
*push_in = gmpfi.push_in;
|
||||
#ifdef _WIN32
|
||||
RECT rect;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
|
||||
gint h = GTK_WIDGET(menu)->requisition.height;
|
||||
if (*y + h > rect.bottom) *y -= h;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _gtk_menu_popup(GtkWidget *menu, GtkWidget *parent_menu_shell, GtkWidget *parent_menu_item, void* data, guint button, guint32 activate_time) {
|
||||
gtk_menu_popup(GTK_MENU(menu), parent_menu_shell, parent_menu_item, _c_gtk_menu_position_func, (gpointer) data, button, activate_time);
|
||||
}
|
||||
|
||||
extern gboolean _go_gtk_tree_selection_select_func(gpointer sel, gpointer model, gpointer path, gboolean selected, gpointer payload);
|
||||
|
||||
static gboolean _c_gtk_tree_selection_select_func(GtkTreeSelection *sel, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer payload) {
|
||||
return _go_gtk_tree_selection_select_func(sel, model, path, selected, payload);
|
||||
}
|
||||
|
||||
static void _go_gtk_tree_selection_set_select_function(GtkTreeSelection *sel, void * payload) {
|
||||
gtk_tree_selection_set_select_function(sel, _c_gtk_tree_selection_select_func, payload, NULL);
|
||||
}
|
||||
|
||||
static void _gtk_container_child_set_bool(GtkContainer* container, GtkWidget* child, const gchar* propname, gboolean value) {
|
||||
gtk_container_child_set(container, child, propname, value, NULL);
|
||||
}
|
||||
|
||||
static void _gtk_container_child_set_int(GtkContainer* container, GtkWidget* child, const gchar* propname, gint value) {
|
||||
gtk_container_child_set(container, child, propname, value, NULL);
|
||||
}
|
||||
|
||||
static inline GType* make_gtypes(int count) {
|
||||
return g_new0(GType, count);
|
||||
}
|
||||
|
||||
static inline void destroy_gtypes(GType* types) {
|
||||
g_free(types);
|
||||
}
|
||||
|
||||
static inline void set_gtype(GType* types, int n, int type) {
|
||||
types[n] = (GType) type;
|
||||
}
|
||||
|
||||
static inline gchar** make_strings(int count) {
|
||||
return (gchar**)malloc(sizeof(gchar*) * count);
|
||||
}
|
||||
|
||||
static inline void destroy_strings(gchar** strings) {
|
||||
free(strings);
|
||||
}
|
||||
|
||||
static inline gchar* get_string(gchar** strings, int n) {
|
||||
return strings[n];
|
||||
}
|
||||
|
||||
static inline void set_string(gchar** strings, int n, gchar* str) {
|
||||
strings[n] = str;
|
||||
}
|
||||
|
||||
static GSList* to_gslist(void* gs) {
|
||||
return (GSList*)gs;
|
||||
}
|
||||
|
||||
static int _check_version(int major, int minor, int micro) {
|
||||
return GTK_CHECK_VERSION(major, minor, micro);
|
||||
}
|
||||
|
||||
static void _gtk_tree_iter_assign(void* iter, void* to) {
|
||||
*(GtkTreeIter*)iter = *(GtkTreeIter*)to;
|
||||
}
|
||||
|
||||
static GtkWidget* _gtk_dialog_get_vbox(GtkWidget* w) {
|
||||
return GTK_DIALOG(w)->vbox;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// ############# Version Control #############
|
||||
//////////////////////////////////////////////
|
||||
|
||||
#if GTK_CHECK_VERSION(2,14,0)
|
||||
static gdouble _gtk_adjustment_get_lower(GtkAdjustment* adjustment) {
|
||||
return gtk_adjustment_get_lower(adjustment);
|
||||
}
|
||||
static void _gtk_adjustment_set_lower(GtkAdjustment* adjustment, gdouble lower) {
|
||||
gtk_adjustment_set_lower(adjustment, lower);
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_upper(GtkAdjustment* adjustment) {
|
||||
return gtk_adjustment_get_upper(adjustment);
|
||||
}
|
||||
static void _gtk_adjustment_set_upper(GtkAdjustment* adjustment, gdouble upper) {
|
||||
gtk_adjustment_set_upper(adjustment, upper);
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_step_increment(GtkAdjustment* adjustment) {
|
||||
return gtk_adjustment_get_step_increment(adjustment);
|
||||
}
|
||||
static void _gtk_adjustment_set_step_increment(GtkAdjustment* adjustment, gdouble step_increment) {
|
||||
gtk_adjustment_set_step_increment(adjustment, step_increment);
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_page_increment(GtkAdjustment* adjustment) {
|
||||
return gtk_adjustment_get_page_increment(adjustment);
|
||||
}
|
||||
static void _gtk_adjustment_set_page_increment(GtkAdjustment* adjustment, gdouble page_increment) {
|
||||
gtk_adjustment_set_page_increment(adjustment, page_increment);
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_page_size(GtkAdjustment* adjustment) {
|
||||
return gtk_adjustment_get_page_size(adjustment);
|
||||
}
|
||||
static void _gtk_adjustment_set_page_size(GtkAdjustment* adjustment, gdouble page_size) {
|
||||
gtk_adjustment_set_page_size(adjustment, page_size);
|
||||
}
|
||||
static void _gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size) {
|
||||
gtk_adjustment_configure(adjustment, value, lower, upper, step_increment, page_increment, page_size);
|
||||
}
|
||||
#else //GTK_CHECK_VERSION(2,14,0)
|
||||
static gdouble _gtk_adjustment_get_lower(GtkAdjustment* adjustment) {
|
||||
return 0f;
|
||||
}
|
||||
static void _gtk_adjustment_set_lower(GtkAdjustment* adjustment, gdouble lower) {
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_upper(GtkAdjustment* adjustment) {
|
||||
return 0f;
|
||||
}
|
||||
static void _gtk_adjustment_set_upper(GtkAdjustment* adjustment, gdouble upper) {
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_step_increment(GtkAdjustment* adjustment) {
|
||||
return 0f;
|
||||
}
|
||||
static void _gtk_adjustment_set_step_increment(GtkAdjustment* adjustment, gdouble step_increment) {
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_page_increment(GtkAdjustment* adjustment) {
|
||||
return 0f;
|
||||
}
|
||||
static void _gtk_adjustment_set_page_increment(GtkAdjustment* adjustment, gdouble page_increment) {
|
||||
}
|
||||
static gdouble _gtk_adjustment_get_page_size(GtkAdjustment* adjustment) {
|
||||
return 0f;
|
||||
}
|
||||
static void _gtk_adjustment_set_page_size(GtkAdjustment* adjustment, gdouble page_size) {
|
||||
}
|
||||
static void _gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size) {
|
||||
}
|
||||
#endif //GTK_CHECK_VERSION(2,14,0)
|
||||
|
||||
#if GTK_CHECK_VERSION(2,18,0)
|
||||
static gboolean _gtk_cell_renderer_toggle_get_activatable(GtkCellRendererToggle *toggle) {
|
||||
return gtk_cell_renderer_toggle_get_activatable(toggle);
|
||||
}
|
||||
static void _gtk_cell_renderer_toggle_set_activatable(GtkCellRendererToggle *toggle, gboolean setting) {
|
||||
gtk_cell_renderer_toggle_set_activatable(toggle, setting);
|
||||
}
|
||||
static void _gtk_menu_set_reserve_toggle_size(GtkMenu *menu, gboolean reserve_toggle_size) {
|
||||
gtk_menu_set_reserve_toggle_size(menu, reserve_toggle_size);
|
||||
}
|
||||
static gboolean _gtk_menu_get_reserve_toggle_size(GtkMenu *menu) {
|
||||
return gtk_menu_get_reserve_toggle_size(menu);
|
||||
}
|
||||
static gboolean _gtk_range_get_flippable(GtkRange *range) {
|
||||
return gtk_range_get_flippable(range);
|
||||
}
|
||||
static void _gtk_range_set_flippable(GtkRange *range, gboolean flippable) {
|
||||
gtk_range_set_flippable(range, flippable);
|
||||
}
|
||||
static void _gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation) {
|
||||
gtk_widget_get_allocation(widget, allocation);
|
||||
}
|
||||
static void _gtk_widget_set_allocation(GtkWidget *widget, const GtkAllocation *allocation) {
|
||||
gtk_widget_set_allocation(widget, allocation);
|
||||
}
|
||||
static gboolean _gtk_widget_get_app_paintable(GtkWidget *widget) {
|
||||
return gtk_widget_get_app_paintable(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_get_can_default(GtkWidget *widget) {
|
||||
return gtk_widget_get_can_default(widget);
|
||||
}
|
||||
static void _gtk_widget_set_can_default(GtkWidget *widget, gboolean can_default) {
|
||||
gtk_widget_set_can_default(widget, can_default);
|
||||
}
|
||||
static gboolean _gtk_widget_get_can_focus(GtkWidget *widget) {
|
||||
return gtk_widget_get_can_focus(widget);
|
||||
}
|
||||
static void _gtk_widget_set_can_focus(GtkWidget *widget, gboolean can_focus) {
|
||||
gtk_widget_set_can_focus(widget, can_focus);
|
||||
}
|
||||
static gboolean _gtk_widget_get_double_buffered(GtkWidget *widget) {
|
||||
return gtk_widget_get_double_buffered(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_get_has_window(GtkWidget *widget) {
|
||||
return gtk_widget_get_has_window(widget);
|
||||
}
|
||||
static void _gtk_widget_set_has_window(GtkWidget *widget, gboolean has_window) {
|
||||
gtk_widget_set_has_window(widget, has_window);
|
||||
}
|
||||
static gboolean _gtk_widget_get_sensitive(GtkWidget *widget) {
|
||||
return gtk_widget_get_sensitive(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_is_sensitive(GtkWidget *widget) {
|
||||
return gtk_widget_is_sensitive(widget);
|
||||
}
|
||||
static GtkStateType _gtk_widget_get_state(GtkWidget *widget) {
|
||||
return gtk_widget_get_state(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_get_visible(GtkWidget *widget) {
|
||||
return gtk_widget_get_visible(widget);
|
||||
}
|
||||
static void _gtk_widget_set_visible(GtkWidget *widget, gboolean visible) {
|
||||
gtk_widget_set_visible(widget, visible);
|
||||
}
|
||||
static gboolean _gtk_widget_has_default(GtkWidget *widget) {
|
||||
return gtk_widget_has_default(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_has_focus(GtkWidget *widget) {
|
||||
return gtk_widget_has_focus(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_has_grab(GtkWidget *widget) {
|
||||
return gtk_widget_has_grab(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_is_drawable(GtkWidget *widget) {
|
||||
return gtk_widget_is_drawable(widget);
|
||||
}
|
||||
static gboolean _gtk_widget_is_toplevel(GtkWidget *widget) {
|
||||
return gtk_widget_is_toplevel(widget);
|
||||
}
|
||||
static void _gtk_widget_set_window(GtkWidget *widget, GdkWindow *window) {
|
||||
gtk_widget_set_window(widget, window);
|
||||
}
|
||||
static void _gtk_widget_set_receives_default(GtkWidget *widget, gboolean receives_default) {
|
||||
gtk_widget_set_receives_default(widget, receives_default);
|
||||
}
|
||||
static gboolean _gtk_widget_get_receives_default(GtkWidget *widget) {
|
||||
return gtk_widget_get_receives_default(widget);
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_new() {
|
||||
return gtk_info_bar_new();
|
||||
}
|
||||
static void _gtk_info_bar_add_action_widget(GtkInfoBar *info_bar, GtkWidget *child, gint response_id) {
|
||||
gtk_info_bar_add_action_widget(info_bar, child, response_id);
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_add_button(GtkInfoBar *info_bar, const gchar *button_text, gint response_id) {
|
||||
return gtk_info_bar_add_button(info_bar, button_text, response_id);
|
||||
}
|
||||
static void _gtk_info_bar_set_response_sensitive(GtkInfoBar *info_bar, gint response_id, gboolean setting) {
|
||||
gtk_info_bar_set_response_sensitive(info_bar, response_id, setting);
|
||||
}
|
||||
static void _gtk_info_bar_set_default_response(GtkInfoBar *info_bar, gint response_id) {
|
||||
gtk_info_bar_set_default_response(info_bar, response_id);
|
||||
}
|
||||
static void _gtk_info_bar_response(GtkInfoBar *info_bar, gint response_id) {
|
||||
gtk_info_bar_response(info_bar, response_id);
|
||||
}
|
||||
static void _gtk_info_bar_set_message_type(GtkInfoBar *info_bar, GtkMessageType message_type) {
|
||||
gtk_info_bar_set_message_type(info_bar, message_type);
|
||||
}
|
||||
static GtkMessageType _gtk_info_bar_get_message_type(GtkInfoBar *info_bar) {
|
||||
return gtk_info_bar_get_message_type(info_bar);
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_get_action_area(GtkInfoBar *info_bar) {
|
||||
return gtk_info_bar_get_action_area(info_bar);
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_get_content_area(GtkInfoBar *info_bar) {
|
||||
return gtk_info_bar_get_content_area(info_bar);
|
||||
}
|
||||
static GtkWidget* _gtk_entry_new_with_buffer(GtkEntryBuffer *buffer) {
|
||||
return gtk_entry_new_with_buffer(buffer);
|
||||
}
|
||||
static GtkEntryBuffer* _gtk_entry_get_buffer(GtkEntry *entry) {
|
||||
return gtk_entry_get_buffer(entry);
|
||||
}
|
||||
static void _gtk_entry_set_buffer(GtkEntry *entry, GtkEntryBuffer *buffer) {
|
||||
gtk_entry_set_buffer(entry, buffer);
|
||||
}
|
||||
static GtkEntryBuffer* _gtk_entry_buffer_new(const gchar *initial_chars, gint n_initial_chars) {
|
||||
return gtk_entry_buffer_new(initial_chars, n_initial_chars);
|
||||
}
|
||||
static const gchar* _gtk_entry_buffer_get_text(GtkEntryBuffer *buffer) {
|
||||
return gtk_entry_buffer_get_text(buffer);
|
||||
}
|
||||
static void _gtk_entry_buffer_set_text(GtkEntryBuffer *buffer, const gchar *chars, gint n_chars) {
|
||||
gtk_entry_buffer_set_text(buffer, chars, n_chars);
|
||||
}
|
||||
//static gsize _gtk_entry_buffer_get_bytes(GtkEntryBuffer *buffer) {
|
||||
// return gtk_entry_buffer_get_bytes(buffer);
|
||||
//}
|
||||
static guint _gtk_entry_buffer_get_length(GtkEntryBuffer *buffer) {
|
||||
return gtk_entry_buffer_get_length(buffer);
|
||||
}
|
||||
static gint _gtk_entry_buffer_get_max_length(GtkEntryBuffer *buffer) {
|
||||
return gtk_entry_buffer_get_max_length(buffer);
|
||||
}
|
||||
static void _gtk_entry_buffer_set_max_length(GtkEntryBuffer *buffer, gint max_length) {
|
||||
gtk_entry_buffer_set_max_length(buffer, max_length);
|
||||
}
|
||||
static guint _gtk_entry_buffer_insert_text(GtkEntryBuffer *buffer, guint position, const gchar *chars, gint n_chars) {
|
||||
return gtk_entry_buffer_insert_text(buffer, position, chars, n_chars);
|
||||
}
|
||||
static guint _gtk_entry_buffer_delete_text(GtkEntryBuffer *buffer, guint position, gint n_chars) {
|
||||
return gtk_entry_buffer_delete_text(buffer, position, n_chars);
|
||||
}
|
||||
static void _gtk_status_icon_set_title(GtkStatusIcon *status_icon, const gchar *title) {
|
||||
gtk_status_icon_set_title(status_icon, title);
|
||||
}
|
||||
static const gchar* _gtk_status_icon_get_title(GtkStatusIcon *status_icon) {
|
||||
return gtk_status_icon_get_title(status_icon);
|
||||
}
|
||||
#else //!GTK_CHECK_VERSION(2,18,0)
|
||||
static gboolean _gtk_cell_renderer_toggle_get_activatable(GtkCellRendererToggle *toggle) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_cell_renderer_toggle_set_activatable(GtkCellRendererToggle *toggle, gboolean setting) {
|
||||
}
|
||||
static void _gtk_menu_set_reserve_toggle_size(GtkMenu *menu, gboolean reserve_toggle_size) {
|
||||
}
|
||||
static gboolean _gtk_menu_get_reserve_toggle_size(GtkMenu *menu) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_range_get_flippable(GtkRange *range) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_range_set_flippable(GtkRange *range, gboolean flippable) {
|
||||
}
|
||||
static void _gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation) {
|
||||
}
|
||||
static void _gtk_widget_set_allocation(GtkWidget *widget, const GtkAllocation *allocation) {
|
||||
}
|
||||
static gboolean _gtk_widget_get_app_paintable(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_get_can_default(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_widget_set_can_default(GtkWidget *widget, gboolean can_default) {
|
||||
}
|
||||
static gboolean _gtk_widget_get_can_focus(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_widget_set_can_focus(GtkWidget *widget, gboolean can_focus) {
|
||||
}
|
||||
static gboolean _gtk_widget_get_double_buffered(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_get_has_window(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_widget_set_has_window(GtkWidget *widget, gboolean has_window) {
|
||||
}
|
||||
static gboolean _gtk_widget_get_sensitive(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_is_sensitive(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static GtkStateType _gtk_widget_get_state(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_get_visible(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_widget_set_visible(GtkWidget *widget, gboolean visible) {
|
||||
}
|
||||
static gboolean _gtk_widget_has_default(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_has_focus(GtkWidget *widget) {
|
||||
return 0:
|
||||
}
|
||||
static gboolean _gtk_widget_has_grab(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static gboolean _gtk_widget_is_drawable(GtkWidget *widget) {
|
||||
return 0:
|
||||
}
|
||||
static gboolean _gtk_widget_is_toplevel(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_widget_set_window(GtkWidget *widget, GdkWindow *window) {
|
||||
}
|
||||
static void _gtk_widget_set_receives_default(GtkWidget *widget, gboolean receives_default) {
|
||||
}
|
||||
static gboolean _gtk_widget_get_receives_default(GtkWidget *widget) {
|
||||
return 0;
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_new() {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_info_bar_add_action_widget(GtkInfoBar *info_bar, GtkWidget *child, gint response_id) {
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_add_button(GtkInfoBar *info_bar, const gchar *button_text, gint response_id) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_info_bar_set_response_sensitive(GtkInfoBar *info_bar, gint response_id, gboolean setting) {
|
||||
}
|
||||
static void _gtk_info_bar_set_default_response(GtkInfoBar *info_bar, gint response_id) {
|
||||
}
|
||||
static void _gtk_info_bar_response(GtkInfoBar *info_bar, gint response_id) {
|
||||
}
|
||||
static void _gtk_info_bar_set_message_type(GtkInfoBar *info_bar, GtkMessageType message_type) {
|
||||
}
|
||||
static GtkMessageType _gtk_info_bar_get_message_type(GtkInfoBar *info_bar) {
|
||||
return 0;
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_get_action_area(GtkInfoBar *info_bar) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkWidget* _gtk_info_bar_get_content_area(GtkInfoBar *info_bar) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkWidget* _gtk_entry_new_with_buffer(GtkEntryBuffer *buffer) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkEntryBuffer* _gtk_entry_get_buffer(GtkEntry *entry) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_entry_set_buffer(GtkEntry *entry, GtkEntryBuffer *buffer) {
|
||||
}
|
||||
static GtkEntryBuffer* _gtk_entry_buffer_new(const gchar *initial_chars, gint n_initial_chars) {
|
||||
return NULL;
|
||||
}
|
||||
static const gchar* _gtk_entry_buffer_get_text(GtkEntryBuffer *buffer) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_entry_buffer_set_text(GtkEntryBuffer *buffer, const gchar *chars, gint n_chars) {
|
||||
}
|
||||
//static gsize _gtk_entry_buffer_get_bytes(GtkEntryBuffer *buffer) {
|
||||
// return 0;
|
||||
//}
|
||||
static guint _gtk_entry_buffer_get_length(GtkEntryBuffer *buffer) {
|
||||
return 0;
|
||||
}
|
||||
static gint _gtk_entry_buffer_get_max_length(GtkEntryBuffer *buffer) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_entry_buffer_set_max_length(GtkEntryBuffer *buffer, gint max_length) {
|
||||
}
|
||||
static guint _gtk_entry_buffer_insert_text(GtkEntryBuffer *buffer, guint position, const gchar *chars, gint n_chars) {
|
||||
return 0;
|
||||
}
|
||||
static guint _gtk_entry_buffer_delete_text(GtkEntryBuffer *buffer, guint position, gint n_chars) {
|
||||
return 0;
|
||||
}
|
||||
static void _gtk_status_icon_set_title(GtkStatusIcon *status_icon, const gchar *title) {
|
||||
}
|
||||
static const gchar* _gtk_status_icon_get_title(GtkStatusIcon *status_icon) {
|
||||
return NULL;
|
||||
}
|
||||
#endif //GTK_CHECK_VERSION(2,18,0)
|
||||
|
||||
#if GTK_CHECK_VERSION(2,20,0)
|
||||
static GtkWidget* _gtk_dialog_get_widget_for_response(GtkDialog* dialog, gint id) {
|
||||
return gtk_dialog_get_widget_for_response(dialog, id);
|
||||
}
|
||||
static GdkWindow* _gtk_viewport_get_bin_window(GtkViewport *viewport) {
|
||||
return gtk_viewport_get_bin_window(viewport);
|
||||
}
|
||||
static void _gtk_status_icon_set_name(GtkStatusIcon *status_icon, const gchar *name) {
|
||||
gtk_status_icon_set_name(status_icon, name);
|
||||
}
|
||||
#else //GTK_CHECK_VERSION(2,20,0)
|
||||
static GtkWidget* _gtk_dialog_get_widget_for_response(GtkDialog* dialog, gint id) {
|
||||
return NULL;
|
||||
}
|
||||
static GdkWindow* _gtk_viewport_get_bin_window(GtkViewport *viewport) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_status_icon_set_name(GtkStatusIcon *status_icon, const gchar *name) {
|
||||
}
|
||||
#endif //GTK_CHECK_VERSION(2,20,0)
|
||||
|
||||
#if GTK_CHECK_VERSION(2,22,0)
|
||||
static GtkWidget* _gtk_accessible_get_widget(GtkAccessible *accessible) {
|
||||
return gtk_accessible_get_widget(accessible);
|
||||
}
|
||||
static void _gtk_accessible_set_widget(GtkAccessible *accessible, GtkWidget *widget) {
|
||||
gtk_accessible_set_widget(accessible, widget);
|
||||
}
|
||||
static GdkWindow* _gtk_viewport_get_view_window(GtkViewport *viewport) {
|
||||
return gtk_viewport_get_view_window(viewport);
|
||||
}
|
||||
#else //GTK_CHECK_VERSION(2,22,0)
|
||||
static GtkWidget* _gtk_accessible_get_widget(GtkAccessible *accessible) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_accessible_set_widget(GtkAccessible *accessible, GtkWidget *widget) {
|
||||
}
|
||||
static GdkWindow* _gtk_viewport_get_view_window(GtkViewport *viewport) {
|
||||
return NULL;
|
||||
}
|
||||
#endif //GTK_CHECK_VERSION(2,22,0)
|
||||
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
static GtkWidget* _gtk_combo_box_new_with_entry(void) {
|
||||
return gtk_combo_box_new_with_entry();
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_new_with_model_and_entry(GtkTreeModel *model) {
|
||||
return gtk_combo_box_new_with_model_and_entry(model);
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_text_new(void) {
|
||||
return gtk_combo_box_text_new();
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_text_new_with_entry(void) {
|
||||
return gtk_combo_box_text_new_with_entry();
|
||||
}
|
||||
static void _gtk_combo_box_text_append_text(GtkComboBoxText *combo_box, const gchar *text) {
|
||||
gtk_combo_box_text_append_text(combo_box, text);
|
||||
}
|
||||
static void _gtk_combo_box_text_insert_text(GtkComboBoxText *combo_box, gint position, const gchar *text) {
|
||||
gtk_combo_box_text_insert_text(combo_box, position, text);
|
||||
}
|
||||
static void _gtk_combo_box_text_prepend_text(GtkComboBoxText *combo_box, const gchar *text) {
|
||||
gtk_combo_box_text_prepend_text(combo_box, text);
|
||||
}
|
||||
static void _gtk_combo_box_text_remove(GtkComboBoxText *combo_box, gint position) {
|
||||
gtk_combo_box_text_remove(combo_box, position);
|
||||
}
|
||||
static gchar* _gtk_combo_box_text_get_active_text(GtkComboBoxText *combo_box) {
|
||||
return gtk_combo_box_text_get_active_text(combo_box);
|
||||
}
|
||||
static void _gtk_notebook_set_group_name(GtkNotebook* notebook, const gchar* group_name) {
|
||||
gtk_notebook_set_group_name(notebook, group_name);
|
||||
}
|
||||
static const gchar* _gtk_notebook_get_group_name(GtkNotebook* notebook) {
|
||||
return gtk_notebook_get_group_name(notebook);
|
||||
}
|
||||
#else //GTK_CHECK_VERSION(2,24,0)
|
||||
typedef GtkComboBox GtkComboBoxText;
|
||||
|
||||
static GtkWidget* _gtk_combo_box_new_with_entry(void) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_new_with_model_and_entry(GtkTreeModel *model) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_text_new(void) {
|
||||
return NULL;
|
||||
}
|
||||
static GtkWidget* _gtk_combo_box_text_new_with_entry(void) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_combo_box_text_append_text(GtkComboBoxText *combo_box, const gchar *text) {
|
||||
}
|
||||
static void _gtk_combo_box_text_insert_text(GtkComboBoxText *combo_box, gint position, const gchar *text) {
|
||||
}
|
||||
static void _gtk_combo_box_text_prepend_text(GtkComboBoxText *combo_box, const gchar *text) {
|
||||
}
|
||||
static void _gtk_combo_box_text_remove(GtkComboBoxText *combo_box, gint position) {
|
||||
}
|
||||
static gchar* _gtk_combo_box_text_get_active_text(GtkComboBoxText *combo_box) {
|
||||
return NULL;
|
||||
}
|
||||
static void _gtk_notebook_set_group_name(GtkNotebook* notebook, const gchar* group_name) {
|
||||
}
|
||||
static const gchar* _gtk_notebook_get_group_name(GtkNotebook* notebook) {
|
||||
return NULL;
|
||||
}
|
||||
#endif //GTK_CHECK_VERSION(2,24,0)
|
||||
|
||||
static GtkCellRenderer* _gtk_cell_renderer_spinner_new(void) {
|
||||
#ifdef GTK_CELL_RENDERER_SPINNER //2.20
|
||||
return gtk_cell_renderer_spinner_new();
|
||||
#else
|
||||
return gtk_cell_renderer_spin_new();
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// ################# Casting #################
|
||||
//////////////////////////////////////////////
|
||||
|
||||
static inline void freeCstr(char* s) { free(s); }
|
||||
static inline gchar** nextGstr(gchar** s) { return (s+1); }
|
||||
|
||||
static inline gchar* toGstr(const char* s) { return (gchar*)s; }
|
||||
static inline char* toCstr(const gchar* s) { return (char*)s; }
|
||||
//static inline char* toCstrU(const guchar* s) { return (char*)s; }
|
||||
//static inline char* toCstrV(const void* s) { return (char*)s; }
|
||||
|
||||
static inline GObject* toGObject(void* o) { return G_OBJECT(o); }
|
||||
static inline GValue* toGValue(void* s) { return (GValue*)s; }
|
||||
static inline GtkWindow* toGWindow(GtkWidget* w) { return GTK_WINDOW(w); }
|
||||
static inline GtkDialog* toGDialog(GtkWidget* w) { return GTK_DIALOG(w); }
|
||||
static inline GtkAboutDialog* toGAboutDialog(GtkWidget* w) { return GTK_ABOUT_DIALOG(w); }
|
||||
static inline GtkContainer* toGContainer(GtkWidget* w) { return GTK_CONTAINER(w); }
|
||||
static inline GtkFileChooser* toGFileChooser(GtkWidget* w) { return GTK_FILE_CHOOSER(w); }
|
||||
static inline GtkFontSelection* toGFontSelection(GtkWidget* w) { return GTK_FONT_SELECTION(w); }
|
||||
static inline GtkFontSelectionDialog* toGFontSelectionDialog(GtkWidget* w) { return GTK_FONT_SELECTION_DIALOG(w); }
|
||||
static inline GtkMisc* toGMisc(GtkWidget* w) { return GTK_MISC(w); }
|
||||
static inline GtkLabel* toGLabel(GtkWidget* w) { return GTK_LABEL(w); }
|
||||
static inline GtkButton* toGButton(GtkWidget* w) { return GTK_BUTTON(w); }
|
||||
static inline GtkSpinButton* toGSpinButton(GtkWidget* w) { return GTK_SPIN_BUTTON(w); }
|
||||
static inline GtkRadioButton* toGRadioButton(GtkWidget* w) { return GTK_RADIO_BUTTON(w); }
|
||||
static inline GtkFontButton* toGFontButton(GtkWidget* w) { return GTK_FONT_BUTTON(w); }
|
||||
static inline GtkLinkButton* toGLinkButton(GtkWidget* w) { return GTK_LINK_BUTTON(w); }
|
||||
static inline GtkComboBox* toGComboBox(GtkWidget* w) { return GTK_COMBO_BOX(w); }
|
||||
static inline GtkComboBoxEntry* toGComboBoxEntry(GtkWidget* w) { return GTK_COMBO_BOX_ENTRY(w); }
|
||||
static inline GtkMessageDialog* toGMessageDialog(GtkWidget* w) { return GTK_MESSAGE_DIALOG(w); }
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
static inline GtkComboBoxText* toGComboBoxText(GtkWidget* w) { return GTK_COMBO_BOX_TEXT(w); }
|
||||
#else
|
||||
static inline GtkComboBoxText* toGComboBoxText(GtkWidget* w) { return w; }
|
||||
#endif
|
||||
static inline GtkAccessible* toGAccessible(void* w) { return GTK_ACCESSIBLE(w); }
|
||||
static inline GtkBin* toGBin(GtkWidget* w) { return GTK_BIN(w); }
|
||||
static inline GtkStatusbar* toGStatusbar(GtkWidget* w) { return GTK_STATUSBAR(w); }
|
||||
static inline GtkInfoBar* toGInfoBar(GtkWidget* w) { return GTK_INFO_BAR(w); }
|
||||
static inline GtkFrame* toGFrame(GtkWidget* w) { return GTK_FRAME(w); }
|
||||
static inline GtkBox* toGBox(GtkWidget* w) { return GTK_BOX(w); }
|
||||
static inline GtkPaned* toGPaned(GtkWidget* w) { return GTK_PANED(w); }
|
||||
static inline GtkToggleButton* toGToggleButton(GtkWidget* w) { return GTK_TOGGLE_BUTTON(w); }
|
||||
static inline GtkAccelLabel* toGAccelLabel(GtkWidget* w) { return GTK_ACCEL_LABEL(w); }
|
||||
static inline GtkEntry* toGEntry(GtkWidget* w) { return GTK_ENTRY(w); }
|
||||
static inline GtkScaleButton* toGScaleButton(GtkWidget* w) { return GTK_SCALE_BUTTON(w); }
|
||||
static inline GtkStyle* toGStyle(GtkObject* o) { return GTK_STYLE(o); }
|
||||
static inline GtkAdjustment* toGAdjustment(GtkObject* o) { return GTK_ADJUSTMENT(o); }
|
||||
static inline GtkArrow* toGArrow(GtkWidget* w) { return GTK_ARROW(w); }
|
||||
static inline GtkTextView* toGTextView(GtkWidget* w) { return GTK_TEXT_VIEW(w); }
|
||||
static inline GtkTextBuffer* toGTextBuffer(void* w) { return GTK_TEXT_BUFFER(w); }
|
||||
static inline GtkTextTag* toGTextTag(void* o) { return GTK_TEXT_TAG(o); }
|
||||
static inline GtkMenu* toGMenu(GtkWidget* w) { return GTK_MENU(w); }
|
||||
static inline GtkMenuBar* toGMenuBar(GtkWidget* w) { return GTK_MENU_BAR(w); }
|
||||
static inline GtkMenuShell* toGMenuShell(GtkWidget* w) { return GTK_MENU_SHELL(w); }
|
||||
static inline GtkMenuItem* toGMenuItem(GtkWidget* w) { return GTK_MENU_ITEM(w); }
|
||||
static inline GtkItem* toGItem(GtkWidget* w) { return GTK_ITEM(w); }
|
||||
static inline GtkToolbar* toGToolbar(GtkWidget* w) { return GTK_TOOLBAR(w); }
|
||||
static inline GtkToolItem* toGToolItem(GtkWidget* w) { return GTK_TOOL_ITEM(w); }
|
||||
static inline GtkSeparatorToolItem* toGSeparatorToolItem(GtkWidget* w) { return GTK_SEPARATOR_TOOL_ITEM(w); }
|
||||
static inline GtkToolButton* toGToolButton(GtkWidget* w) { return GTK_TOOL_BUTTON(w); }
|
||||
static inline GtkToolPalette* toGToolPalette(GtkWidget* w) { return GTK_TOOL_PALETTE(w); }
|
||||
static inline GtkToolItemGroup* toGToolItemGroup(GtkWidget* w) { return GTK_TOOL_ITEM_GROUP(w); }
|
||||
static inline GtkMenuToolButton* toGMenuToolButton(GtkWidget* w) { return GTK_MENU_TOOL_BUTTON(w); }
|
||||
static inline GtkToggleToolButton* toGToggleToolButton(GtkWidget* w) { return GTK_TOGGLE_TOOL_BUTTON(w); }
|
||||
static inline GtkScrolledWindow* toGScrolledWindow(GtkWidget* w) { return GTK_SCROLLED_WINDOW(w); }
|
||||
static inline GtkViewport* toGViewport(GtkWidget* w) { return GTK_VIEWPORT(w); }
|
||||
static inline GtkWidget* toGWidget(void* w) { return GTK_WIDGET(w); }
|
||||
static inline GdkWindow* toGdkWindow(void* w) { return GDK_WINDOW(w); }
|
||||
static inline GdkScreen* toGdkScreen(void* s) { return GDK_SCREEN(s); }
|
||||
static inline GtkTreeView* toGTreeView(GtkWidget* w) { return GTK_TREE_VIEW(w); }
|
||||
static inline GtkIconView* toGIconView(GtkWidget* w) { return GTK_ICON_VIEW(w); }
|
||||
static inline GtkTreeSortable* toGTreeSortable(GtkTreeModel* m) { return GTK_TREE_SORTABLE(m); }
|
||||
static inline GtkEditable* toGEditable(GtkWidget* w) { return GTK_EDITABLE(w); }
|
||||
static inline GtkCellRendererText* toGCellRendererText(GtkCellRenderer* w) { return GTK_CELL_RENDERER_TEXT(w); }
|
||||
static inline GtkCellRendererToggle* toGCellRendererToggle(GtkCellRenderer* w) { return GTK_CELL_RENDERER_TOGGLE(w); }
|
||||
static inline GtkScale* toGScale(GtkWidget* w) { return GTK_SCALE(w); }
|
||||
static inline GtkRange* toGRange(GtkWidget* w) { return GTK_RANGE(w); }
|
||||
static inline GtkTreeModel* toGTreeModelFromListStore(GtkListStore* w) { return GTK_TREE_MODEL(w); }
|
||||
static inline GtkTreeModel* toGTreeModelFromTreeStore(GtkTreeStore* w) { return GTK_TREE_MODEL(w); }
|
||||
static inline GtkListStore* toGListStore(void* w) { return GTK_LIST_STORE(w); }
|
||||
static inline GtkImage* toGImage(GtkWidget* w) { return GTK_IMAGE(w); }
|
||||
static inline GtkNotebook* toGNotebook(GtkWidget* w) { return GTK_NOTEBOOK(w); }
|
||||
static inline GtkTable* toGTable(GtkWidget* w) { return GTK_TABLE(w); }
|
||||
static inline GtkDrawingArea* toGDrawingArea(GtkWidget* w) { return GTK_DRAWING_AREA(w); }
|
||||
static inline GtkSpinner* toGSpinner(GtkWidget* w) { return GTK_SPINNER(w); }
|
||||
static inline GtkAssistant* toGAssistant(GtkWidget* w) { return GTK_ASSISTANT(w); }
|
||||
static inline GtkExpander* toGExpander(GtkWidget* w) { return GTK_EXPANDER(w); }
|
||||
static inline GtkAlignment* toGAlignment(GtkWidget* w) { return GTK_ALIGNMENT(w); }
|
||||
static inline GtkProgressBar* toGProgressBar(GtkWidget* w) { return GTK_PROGRESS_BAR(w); }
|
||||
static inline GtkFixed* toGFixed(GtkWidget* w) { return GTK_FIXED(w); }
|
||||
static inline GtkCheckMenuItem* toGCheckMenuItem(GtkWidget* w) { return GTK_CHECK_MENU_ITEM(w); }
|
||||
static inline GtkRadioMenuItem* toGRadioMenuItem(GtkWidget* w) { return GTK_RADIO_MENU_ITEM(w); }
|
||||
static inline GtkFileFilter* toGFileFilter(gpointer p) { return GTK_FILE_FILTER(p); }
|
||||
static inline GtkTreePath* to_GTreePath(gpointer p) { return (GtkTreePath *)p; }
|
||||
static inline GtkTreeSelection* to_GTreeSelection(void *p) { return GTK_TREE_SELECTION(p); }
|
||||
static inline GtkTreeModel* to_GTreeModel(void *p) { return GTK_TREE_MODEL(p); }
|
||||
static inline GtkLayout* toGLayout(GtkWidget* w) { return GTK_LAYOUT(w); }
|
||||
static inline GtkColorButton* toGColorButton(GtkWidget* w) { return GTK_COLOR_BUTTON(w); }
|
||||
static inline GtkImageMenuItem* toGImageMenuItem(GtkWidget* w) { return GTK_IMAGE_MENU_ITEM(w); }
|
||||
static inline GtkAction* toGAction(void* o) { return GTK_ACTION(o); }
|
||||
static inline GtkToggleAction* toGToggleAction(void* o) { return GTK_TOGGLE_ACTION(o); }
|
||||
static inline GtkRadioAction* toGRadioAction(void* o) { return GTK_RADIO_ACTION(o); }
|
||||
static inline GtkRecentAction* toGRecentAction(void* o) { return GTK_RECENT_ACTION(o); }
|
||||
static inline GtkActionGroup* toGActionGroup(void* o) { return GTK_ACTION_GROUP(o); }
|
||||
static inline GtkActivatable* toGActivatable(GtkWidget* w) { return GTK_ACTIVATABLE(w); }
|
||||
static inline GtkUIManager* toGUIManager(void* o) { return GTK_UI_MANAGER(o); }
|
||||
#endif
|
58
vendor/github.com/mattn/go-gtk/gtk/gtk_test.go
generated
vendored
Normal file
58
vendor/github.com/mattn/go-gtk/gtk/gtk_test.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package gtk
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUpdateTreeViewColumns(t *testing.T) {
|
||||
Init(nil)
|
||||
|
||||
columnsDesc := []struct {
|
||||
Title string
|
||||
Type string
|
||||
GTKType ICellRenderer
|
||||
}{
|
||||
{"Col_1", "text", NewCellRendererText()},
|
||||
{"Col_2", "text", NewCellRendererText()},
|
||||
}
|
||||
|
||||
tw := NewTreeView()
|
||||
for i, c := range columnsDesc {
|
||||
tw.AppendColumn(NewTreeViewColumnWithAttributes(c.Title, c.GTKType, c.Type, i))
|
||||
}
|
||||
|
||||
columns := tw.GetColumns()
|
||||
|
||||
if len(columns) != len(columnsDesc) {
|
||||
t.Error("Wrong number of the columns:", len(columns), len(columnsDesc))
|
||||
} else {
|
||||
|
||||
for i, _ := range columnsDesc {
|
||||
if columns[i].GetTitle() != columnsDesc[i].Title {
|
||||
t.Error("Wrong column title:", columns[i].GetTitle(), columnsDesc[i].Title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for lastIndex := len(columns) - 1; lastIndex >= 0; {
|
||||
c := columns[lastIndex]
|
||||
|
||||
after := tw.RemoveColumn(c)
|
||||
|
||||
numbersColumns := lastIndex
|
||||
if numbersColumns != after {
|
||||
t.Error("Failed remove column:", numbersColumns, after)
|
||||
}
|
||||
|
||||
lastIndex -= 1
|
||||
if lastIndex >= 0 {
|
||||
if title := tw.GetColumns()[lastIndex].GetTitle(); title != columnsDesc[lastIndex].Title {
|
||||
t.Error("Wrong column title:", title, columnsDesc[lastIndex].Title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if count := len(tw.GetColumns()); count != 0 {
|
||||
t.Error("Wrong number of the columns:", count)
|
||||
}
|
||||
}
|
13
vendor/github.com/mattn/go-gtk/gtk/gtk_x11.go
generated
vendored
Normal file
13
vendor/github.com/mattn/go-gtk/gtk/gtk_x11.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// +build with-x11
|
||||
|
||||
package gtk
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/gdk"
|
||||
)
|
||||
|
||||
func (v *Window) XID() int32 {
|
||||
return gdk.WindowFromUnsafe(unsafe.Pointer(v.GWidget.window)).GetNativeWindowID()
|
||||
}
|
34
vendor/github.com/mattn/go-gtk/gtkgl/gdkgl.go
generated
vendored
Normal file
34
vendor/github.com/mattn/go-gtk/gtkgl/gdkgl.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gtkgl
|
||||
|
||||
const (
|
||||
ATTR_NONE = 0
|
||||
ATTR_USE_GL = 1
|
||||
ATTR_BUFFER_SIZE = 2
|
||||
ATTR_LEVEL = 3
|
||||
ATTR_RGBA = 4
|
||||
ATTR_DOUBLEBUFFER = 5
|
||||
ATTR_STEREO = 6
|
||||
ATTR_AUX_BUFFERS = 7
|
||||
ATTR_RED_SIZE = 8
|
||||
ATTR_GREEN_SIZE = 9
|
||||
ATTR_BLUE_SIZE = 10
|
||||
ATTR_ALPGHA_SIZE = 11
|
||||
ATTR_DEPTH_SIZE = 12
|
||||
ATTR_STENCIL_SIZE = 13
|
||||
ATTR_ACCUM_RED_SIZE = 14
|
||||
ATTR_ACCUM_GREEN_SIZE = 15
|
||||
ATTR_ACCUM_BLUE_SIZE = 16
|
||||
ATTR_ACCUM_ALPHA_SIZE = 17
|
||||
)
|
||||
|
||||
const (
|
||||
ATTR_X_VISUAL_TYPE_EXT = 0x22
|
||||
ATTR_TRANSPARENT_TYPE_EXT = 0x23
|
||||
ATTR_TRANSPARENT_INDEX_VALUE_EXT = 0x24
|
||||
ATTR_TRANSPARENT_RED_VALUE_EXT = 0x25
|
||||
ATTR_TRANSPARENT_GREEN_VALUE_EXT = 0x26
|
||||
ATTR_TRANSPARENT_BLUE_VALUE_EXT = 0x27
|
||||
ATTR_TRANSPARENT_ALPHA_VALUE_EXT = 0x28
|
||||
)
|
28
vendor/github.com/mattn/go-gtk/gtkgl/gtkgl.go.h
generated
vendored
Normal file
28
vendor/github.com/mattn/go-gtk/gtkgl/gtkgl.go.h
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef GO_GTKGL_H
|
||||
#define GO_GTKGL_H
|
||||
|
||||
#include <gtkgl/gdkgl.h>
|
||||
#include <gtkgl/gtkglarea.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *make_area(int attr_count, int *attrs) {
|
||||
if (attr_count > 0 && attrs[attr_count-1] == 0) {
|
||||
// already null terminated; use the pointer directly
|
||||
return gtk_gl_area_new(attrs);
|
||||
} else {
|
||||
// make a null terminated copy of the attribute list
|
||||
GtkWidget *area = NULL;
|
||||
int *zattrs = malloc((attr_count+1)*sizeof(int));
|
||||
if (!zattrs) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(zattrs, attrs, attr_count * sizeof(attrs));
|
||||
zattrs[attr_count] = 0;
|
||||
area = gtk_gl_area_new(zattrs);
|
||||
free(zattrs);
|
||||
return area;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
vendor/github.com/mattn/go-gtk/gtkgl/gtkglarea.go
generated
vendored
Normal file
27
vendor/github.com/mattn/go-gtk/gtkgl/gtkglarea.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gtkgl
|
||||
|
||||
// #include "gtkgl.go.h"
|
||||
// #cgo pkg-config: gtkgl-2.0
|
||||
import "C"
|
||||
|
||||
import "github.com/mattn/go-gtk/gtk"
|
||||
import "unsafe"
|
||||
|
||||
type GLArea struct {
|
||||
gtk.DrawingArea
|
||||
}
|
||||
|
||||
func NewGLArea(attrList []int) *GLArea {
|
||||
return &GLArea{gtk.DrawingArea{
|
||||
*gtk.WidgetFromNative(C.make_area(C.int(len(attrList)), (*C.int)(unsafe.Pointer(&attrList[0]))))}}
|
||||
}
|
||||
|
||||
func (v *GLArea) MakeCurrent() {
|
||||
C.gtk_gl_area_make_current((*C.GtkGLArea)(unsafe.Pointer(v.GWidget)))
|
||||
}
|
||||
|
||||
func (v *GLArea) SwapBuffers() {
|
||||
C.gtk_gl_area_swap_buffers((*C.GtkGLArea)(unsafe.Pointer(v.GWidget)))
|
||||
}
|
405
vendor/github.com/mattn/go-gtk/gtksourceview/gtksourceview.go
generated
vendored
Normal file
405
vendor/github.com/mattn/go-gtk/gtksourceview/gtksourceview.go
generated
vendored
Normal file
@ -0,0 +1,405 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gtksourceview
|
||||
|
||||
// #include "gtksourceview.go.h"
|
||||
// #cgo pkg-config: gtksourceview-2.0
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
func gstring(s *C.char) *C.gchar { return C.toGstr(s) }
|
||||
func cstring(s *C.gchar) *C.char { return C.toCstr(s) }
|
||||
func gostring(s *C.gchar) string { return C.GoString(cstring(s)) }
|
||||
|
||||
func gbool(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func gobool(b C.gboolean) bool {
|
||||
if b != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func cfree(s *C.char) { C.freeCstr(s) }
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceBuffer
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceBuffer struct {
|
||||
GSourceBuffer *C.GtkSourceBuffer
|
||||
*gtk.TextBuffer
|
||||
}
|
||||
|
||||
func NewSourceBuffer() *SourceBuffer {
|
||||
v := C.gtk_source_buffer_new(nil)
|
||||
return &SourceBuffer{v, gtk.NewTextBufferFromPointer(unsafe.Pointer(v))}
|
||||
}
|
||||
|
||||
func NewSourceBufferWithLanguage(lang *SourceLanguage) *SourceBuffer {
|
||||
v := C.gtk_source_buffer_new_with_language(lang.GSourceLanguage)
|
||||
return &SourceBuffer{v, gtk.NewTextBufferFromPointer(unsafe.Pointer(v))}
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) GetNativeBuffer() unsafe.Pointer {
|
||||
return unsafe.Pointer(v.GSourceBuffer)
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) SetHighlightSyntax(highlight bool) {
|
||||
C.gtk_source_buffer_set_highlight_syntax(v.GSourceBuffer, gbool(highlight))
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) GetHighlightSyntax() bool {
|
||||
return gobool(C.gtk_source_buffer_get_highlight_syntax(v.GSourceBuffer))
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) SetHighlightMatchingBrackets(hl bool) {
|
||||
C.gtk_source_buffer_set_highlight_matching_brackets(v.GSourceBuffer, gbool(hl))
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) SetLanguage(lang *SourceLanguage) {
|
||||
C.gtk_source_buffer_set_language(v.GSourceBuffer, lang.GSourceLanguage)
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) GetLanguage() *SourceLanguage {
|
||||
return &SourceLanguage{C.gtk_source_buffer_get_language(v.GSourceBuffer)}
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) BeginNotUndoableAction() {
|
||||
C.gtk_source_buffer_begin_not_undoable_action(v.GSourceBuffer)
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) EndNotUndoableAction() {
|
||||
C.gtk_source_buffer_end_not_undoable_action(v.GSourceBuffer)
|
||||
}
|
||||
|
||||
func (v *SourceBuffer) SetStyleScheme(scheme *SourceStyleScheme) {
|
||||
C.gtk_source_buffer_set_style_scheme(v.GSourceBuffer, scheme.GSourceStyleScheme)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceView
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceView struct {
|
||||
gtk.TextView
|
||||
}
|
||||
|
||||
func NewSourceView() *SourceView {
|
||||
return &SourceView{gtk.TextView{gtk.Container{
|
||||
*gtk.WidgetFromNative(unsafe.Pointer(C.gtk_source_view_new()))}}}
|
||||
}
|
||||
|
||||
func NewSourceViewWithBuffer(buf *SourceBuffer) *SourceView {
|
||||
return &SourceView{gtk.TextView{gtk.Container{
|
||||
*gtk.WidgetFromNative(unsafe.Pointer(C.gtk_source_view_new_with_buffer(buf.GSourceBuffer)))}}}
|
||||
}
|
||||
|
||||
func (v *SourceView) ToNativeSourceView() *C.GtkSourceView {
|
||||
return C.toGtkSourceView(unsafe.Pointer(v.GWidget))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetAutoIndent(enable bool) {
|
||||
C.gtk_source_view_set_auto_indent(v.ToNativeSourceView(), gbool(enable))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetAutoIndent() bool {
|
||||
return gobool(C.gtk_source_view_get_auto_indent(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetHighlightCurrentLine(enable bool) {
|
||||
C.gtk_source_view_set_highlight_current_line(v.ToNativeSourceView(), gbool(enable))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetHighlightCurrentLine() bool {
|
||||
return gobool(C.gtk_source_view_get_highlight_current_line(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetShowLineNumbers(enable bool) {
|
||||
C.gtk_source_view_set_show_line_numbers(v.ToNativeSourceView(), gbool(enable))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetShowLineNumbers() bool {
|
||||
return gobool(C.gtk_source_view_get_show_line_numbers(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetRightMarginPosition(pos uint) {
|
||||
C.gtk_source_view_set_right_margin_position(v.ToNativeSourceView(), C.guint(pos))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetRightMarginPosition() uint {
|
||||
return uint(C.gtk_source_view_get_right_margin_position(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetIndentWidth(width int) {
|
||||
C.gtk_source_view_set_indent_width(v.ToNativeSourceView(), C.gint(width))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetIndentWidth() int {
|
||||
return int(C.gtk_source_view_get_indent_width(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetShowRightMargin(enable bool) {
|
||||
C.gtk_source_view_set_show_right_margin(v.ToNativeSourceView(), gbool(enable))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetShowRightMargin() bool {
|
||||
return gobool(C.gtk_source_view_get_show_right_margin(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetInsertSpacesInsteadOfTabs(enable bool) {
|
||||
C.gtk_source_view_set_insert_spaces_instead_of_tabs(v.ToNativeSourceView(), gbool(enable))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetInsertSpacesInsteadOfTabs() bool {
|
||||
return gobool(C.gtk_source_view_get_insert_spaces_instead_of_tabs(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
type SourceDrawSpacesFlags int
|
||||
|
||||
const (
|
||||
SOURCE_DRAW_SPACES_SPACE SourceDrawSpacesFlags = 1 << 0
|
||||
SOURCE_DRAW_SPACES_TAB SourceDrawSpacesFlags = 1 << 1
|
||||
SOURCE_DRAW_SPACES_NEWLINE SourceDrawSpacesFlags = 1 << 2
|
||||
SOURCE_DRAW_SPACES_NBSP SourceDrawSpacesFlags = 1 << 3
|
||||
SOURCE_DRAW_SPACES_LEADING SourceDrawSpacesFlags = 1 << 4
|
||||
SOURCE_DRAW_SPACES_TEXT SourceDrawSpacesFlags = 1 << 5
|
||||
SOURCE_DRAW_SPACES_TRAILING SourceDrawSpacesFlags = 1 << 6
|
||||
SOURCE_DRAW_SPACES_ALL SourceDrawSpacesFlags = (SOURCE_DRAW_SPACES_SPACE |
|
||||
SOURCE_DRAW_SPACES_TAB |
|
||||
SOURCE_DRAW_SPACES_NEWLINE |
|
||||
SOURCE_DRAW_SPACES_NBSP |
|
||||
SOURCE_DRAW_SPACES_LEADING |
|
||||
SOURCE_DRAW_SPACES_TEXT |
|
||||
SOURCE_DRAW_SPACES_TRAILING)
|
||||
)
|
||||
|
||||
func (v *SourceView) SetDrawSpaces(flags SourceDrawSpacesFlags) {
|
||||
C.gtk_source_view_set_draw_spaces(v.ToNativeSourceView(),
|
||||
C.GtkSourceDrawSpacesFlags(flags))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetDrawSpaces() SourceDrawSpacesFlags {
|
||||
return SourceDrawSpacesFlags(C.gtk_source_view_get_draw_spaces(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
func (v *SourceView) SetTabWidth(width uint) {
|
||||
C.gtk_source_view_set_tab_width(v.ToNativeSourceView(),
|
||||
C.guint(width))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetTabWidth() uint {
|
||||
return uint(C.gtk_source_view_get_tab_width(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
type SourceSmartHomeEndType int
|
||||
|
||||
const (
|
||||
SOURCE_SMART_HOME_END_DISABLED SourceSmartHomeEndType = 0
|
||||
SOURCE_SMART_HOME_END_BEFORE SourceSmartHomeEndType = 1
|
||||
SOURCE_SMART_HOME_END_AFTER SourceSmartHomeEndType = 2
|
||||
SOURCE_SMART_HOME_END_ALWAYS SourceSmartHomeEndType = 3
|
||||
)
|
||||
|
||||
func (v *SourceView) SetSmartHomeEnd(flags SourceSmartHomeEndType) {
|
||||
C.gtk_source_view_set_smart_home_end(v.ToNativeSourceView(),
|
||||
C.GtkSourceSmartHomeEndType(flags))
|
||||
}
|
||||
|
||||
func (v *SourceView) GetSmartHomeEnd() SourceSmartHomeEndType {
|
||||
return SourceSmartHomeEndType(C.gtk_source_view_get_smart_home_end(v.ToNativeSourceView()))
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceLanguage
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceLanguage struct {
|
||||
GSourceLanguage *C.GtkSourceLanguage
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetId() string {
|
||||
return gostring(C.gtk_source_language_get_id(v.GSourceLanguage))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetName() string {
|
||||
return gostring(C.gtk_source_language_get_name(v.GSourceLanguage))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetSection() string {
|
||||
return gostring(C.gtk_source_language_get_section(v.GSourceLanguage))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetHidden() bool {
|
||||
return gobool(C.gtk_source_language_get_hidden(v.GSourceLanguage))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetMetadata(name string) string {
|
||||
cname := C.CString(name)
|
||||
defer cfree(cname)
|
||||
return gostring(C.gtk_source_language_get_metadata(v.GSourceLanguage, gstring(cname)))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetMimeTypes() []string {
|
||||
var types []string
|
||||
ctypes := C.gtk_source_language_get_mime_types(v.GSourceLanguage)
|
||||
for {
|
||||
types = append(types, gostring(*ctypes))
|
||||
ctypes = C.nextGstr(ctypes)
|
||||
if *ctypes == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetGlobs() []string {
|
||||
var globs []string
|
||||
cglobs := C.gtk_source_language_get_globs(v.GSourceLanguage)
|
||||
for {
|
||||
globs = append(globs, gostring(*cglobs))
|
||||
cglobs = C.nextGstr(cglobs)
|
||||
if *cglobs == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return globs
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetStyleName(styleId string) string {
|
||||
cstyleId := C.CString(styleId)
|
||||
defer cfree(cstyleId)
|
||||
return gostring(C.gtk_source_language_get_metadata(v.GSourceLanguage, gstring(cstyleId)))
|
||||
}
|
||||
|
||||
func (v *SourceLanguage) GetStyleIds() []string {
|
||||
var ids []string
|
||||
cids := C.gtk_source_language_get_globs(v.GSourceLanguage)
|
||||
for {
|
||||
ids = append(ids, gostring(*cids))
|
||||
cids = C.nextGstr(cids)
|
||||
if *cids == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
//FINISH
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceLanguageManager
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceLanguageManager struct {
|
||||
GSourceLanguageManager *C.GtkSourceLanguageManager
|
||||
}
|
||||
|
||||
func NewSourceLanguageManager() *SourceLanguageManager {
|
||||
return &SourceLanguageManager{C.gtk_source_language_manager_new()}
|
||||
}
|
||||
|
||||
func SourceLanguageManagerGetDefault() *SourceLanguageManager {
|
||||
return &SourceLanguageManager{C.gtk_source_language_manager_get_default()}
|
||||
}
|
||||
|
||||
func (v *SourceLanguageManager) SetSearchPath(paths []string) {
|
||||
cpaths := C.make_strings(C.int(len(paths) + 1))
|
||||
for i, path := range paths {
|
||||
ptr := C.CString(path)
|
||||
defer cfree(ptr)
|
||||
C.set_string(cpaths, C.int(i), gstring(ptr))
|
||||
}
|
||||
C.set_string(cpaths, C.int(len(paths)), nil)
|
||||
C.gtk_source_language_manager_set_search_path(v.GSourceLanguageManager, cpaths)
|
||||
C.destroy_strings(cpaths)
|
||||
}
|
||||
|
||||
func (v *SourceLanguageManager) GetSearchPath() []string {
|
||||
var dirs []string
|
||||
cdirs := C.gtk_source_language_manager_get_search_path(v.GSourceLanguageManager)
|
||||
for {
|
||||
dirs = append(dirs, gostring(*cdirs))
|
||||
cdirs = C.nextGstr(cdirs)
|
||||
if *cdirs == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
func (v *SourceLanguageManager) GetLanguageIds() []string {
|
||||
var ids []string
|
||||
cids := C.gtk_source_language_manager_get_language_ids(v.GSourceLanguageManager)
|
||||
for {
|
||||
ids = append(ids, gostring(*cids))
|
||||
cids = C.nextGstr(cids)
|
||||
if *cids == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func (v *SourceLanguageManager) GetLanguage(id string) *SourceLanguage {
|
||||
cid := C.CString(id)
|
||||
defer cfree(cid)
|
||||
return &SourceLanguage{C.gtk_source_language_manager_get_language(v.GSourceLanguageManager, gstring(cid))}
|
||||
}
|
||||
|
||||
func (v *SourceLanguageManager) GuessLanguage(filename string, contentType string) *SourceLanguage {
|
||||
if filename == "" {
|
||||
cct := C.CString(contentType)
|
||||
defer cfree(cct)
|
||||
return &SourceLanguage{C.gtk_source_language_manager_guess_language(v.GSourceLanguageManager, nil, gstring(cct))}
|
||||
}
|
||||
cfn := C.CString(filename)
|
||||
defer cfree(cfn)
|
||||
return &SourceLanguage{C.gtk_source_language_manager_guess_language(v.GSourceLanguageManager, gstring(cfn), nil)}
|
||||
}
|
||||
|
||||
//FINISH
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceStyle
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceStyleScheme struct {
|
||||
GSourceStyleScheme *C.GtkSourceStyleScheme
|
||||
}
|
||||
|
||||
// gtk_source_style_scheme_get_id
|
||||
// gtk_source_style_scheme_get_name
|
||||
// gtk_source_style_scheme_get_description
|
||||
// gtk_source_style_scheme_get_authors
|
||||
// gtk_source_style_scheme_get_filename
|
||||
// gtk_source_style_scheme_get_style
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSourceStyleSchemeManager
|
||||
//-----------------------------------------------------------------------
|
||||
type SourceStyleSchemeManager struct {
|
||||
GSourceStyleSchemeManager *C.GtkSourceStyleSchemeManager
|
||||
}
|
||||
|
||||
func NewSourceStyleSchemeManager() *SourceStyleSchemeManager {
|
||||
return &SourceStyleSchemeManager{C.gtk_source_style_scheme_manager_new()}
|
||||
}
|
||||
|
||||
func (v *SourceStyleSchemeManager) GetScheme(scheme_id string) *SourceStyleScheme {
|
||||
cscheme_id := C.CString(scheme_id)
|
||||
defer cfree(cscheme_id)
|
||||
return &SourceStyleScheme{C.gtk_source_style_scheme_manager_get_scheme(v.GSourceStyleSchemeManager, gstring(cscheme_id))}
|
||||
}
|
||||
|
||||
// gtk_source_style_scheme_manager_get_default
|
||||
// gtk_source_style_scheme_manager_set_search_path
|
||||
// gtk_source_style_scheme_manager_append_search_path
|
||||
// gtk_source_style_scheme_manager_prepend_search_path
|
||||
// gtk_source_style_scheme_manager_get_search_path
|
||||
// gtk_source_style_scheme_manager_get_scheme_ids
|
||||
// gtk_source_style_scheme_manager_force_rescan
|
30
vendor/github.com/mattn/go-gtk/gtksourceview/gtksourceview.go.h
generated
vendored
Normal file
30
vendor/github.com/mattn/go-gtk/gtksourceview/gtksourceview.go.h
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef GO_GTKSOURCEVIEW_H
|
||||
#define GO_GTKSOURCEVIEW_H
|
||||
|
||||
#include <gtksourceview/gtksourceview.h>
|
||||
#include <gtksourceview/gtksourcebuffer.h>
|
||||
#include <gtksourceview/gtksourcelanguage.h>
|
||||
#include <gtksourceview/gtksourcelanguagemanager.h>
|
||||
#include <gtksourceview/gtksourcestyleschememanager.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline gchar** make_strings(int count) {
|
||||
return (gchar**)malloc(sizeof(gchar*) * count);
|
||||
}
|
||||
|
||||
static inline void destroy_strings(gchar** strings) {
|
||||
free(strings);
|
||||
}
|
||||
|
||||
static inline void set_string(gchar** strings, int n, gchar* str) {
|
||||
strings[n] = str;
|
||||
}
|
||||
|
||||
static inline GObject* toGObject(void* o) { return G_OBJECT(o); }
|
||||
static inline gchar* toGstr(const char* s) { return (gchar*)s; }
|
||||
static inline char* toCstr(const gchar* s) { return (char*)s; }
|
||||
static inline gchar** nextGstr(gchar** s) { return (s+1); }
|
||||
static inline void freeCstr(char* s) { free(s); }
|
||||
static GtkSourceView* toGtkSourceView(void* w) { return GTK_SOURCE_VIEW(w); }
|
||||
|
||||
#endif
|
56
vendor/github.com/mattn/go-gtk/gtkspell/gtkspell.go
generated
vendored
Normal file
56
vendor/github.com/mattn/go-gtk/gtkspell/gtkspell.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package gtkspell
|
||||
|
||||
/*
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtkspell/gtkspell.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static GtkTextView* to_GtkTextView(void* w) { return GTK_TEXT_VIEW(w); }
|
||||
static inline gchar* to_gcharptr(const char* s) { return (gchar*)s; }
|
||||
*/
|
||||
// #cgo pkg-config: gtkspell-2.0
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
import "github.com/mattn/go-gtk/glib"
|
||||
import "github.com/mattn/go-gtk/gtk"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// GtkSpell
|
||||
//-----------------------------------------------------------------------
|
||||
type GtkSpell struct {
|
||||
Spell *C.GtkSpell
|
||||
}
|
||||
|
||||
func New(textview *gtk.TextView, language string) (*GtkSpell, *glib.Error) {
|
||||
var lang *C.char
|
||||
if len(language) > 0 {
|
||||
lang = C.CString(language)
|
||||
defer C.free(unsafe.Pointer(lang))
|
||||
}
|
||||
|
||||
var gerror *C.GError
|
||||
v := C.gtkspell_new_attach(C.to_GtkTextView(unsafe.Pointer(&textview.Widget)), C.to_gcharptr(lang), &gerror)
|
||||
if gerror != nil {
|
||||
return nil, glib.ErrorFromNative(unsafe.Pointer(gerror))
|
||||
}
|
||||
return &GtkSpell{v}, nil
|
||||
}
|
||||
|
||||
func (spell *GtkSpell) SetLanguage(language string) *glib.Error {
|
||||
lang := C.CString(language)
|
||||
defer C.free(unsafe.Pointer(lang))
|
||||
|
||||
var gerror *C.GError
|
||||
C.gtkspell_set_language(spell.Spell, C.to_gcharptr(lang), &gerror)
|
||||
if gerror != nil {
|
||||
return glib.ErrorFromNative(unsafe.Pointer(gerror))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (spell *GtkSpell) Recheck() {
|
||||
C.gtkspell_recheck_all(spell.Spell)
|
||||
}
|
101
vendor/github.com/mattn/go-gtk/pango/pango.go
generated
vendored
Normal file
101
vendor/github.com/mattn/go-gtk/pango/pango.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
// +build !cgocheck
|
||||
|
||||
package pango
|
||||
|
||||
// #include "pango.go.h"
|
||||
// #cgo pkg-config: pango
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
SCALE = C.PANGO_SCALE
|
||||
)
|
||||
|
||||
func bool2gboolean(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func gboolean2bool(b C.gboolean) bool {
|
||||
if b != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type WrapMode int
|
||||
|
||||
const (
|
||||
WRAP_WORD WrapMode = 0
|
||||
WRAP_CHAR WrapMode = 1
|
||||
WRAP_WORD_CHAR WrapMode = 2
|
||||
)
|
||||
|
||||
type EllipsizeMode int
|
||||
|
||||
const (
|
||||
ELLIPSIZE_NONE EllipsizeMode = 0
|
||||
ELLIPSIZE_START EllipsizeMode = 1
|
||||
ELLIPSIZE_MIDDLE EllipsizeMode = 2
|
||||
ELLIPSIZE_END EllipsizeMode = 3
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
GContext *C.PangoContext
|
||||
}
|
||||
|
||||
type Layout struct {
|
||||
GLayout *C.PangoLayout
|
||||
}
|
||||
|
||||
type FontDescription struct {
|
||||
GFontDescription *C.PangoFontDescription
|
||||
}
|
||||
|
||||
func ContextFromUnsafe(context unsafe.Pointer) *Context {
|
||||
return &Context{(*C.PangoContext)(context)}
|
||||
}
|
||||
|
||||
func (v *Layout) Unref() {
|
||||
C.g_object_unref(C.gpointer(v.GLayout))
|
||||
}
|
||||
|
||||
func (v *Layout) SetWidth(width int) {
|
||||
C.pango_layout_set_width(v.GLayout, C.int(width))
|
||||
}
|
||||
|
||||
func (v *Layout) SetFontDescription(d *FontDescription) {
|
||||
C.pango_layout_set_font_description(v.GLayout, d.GFontDescription)
|
||||
}
|
||||
|
||||
func (v *Layout) SetText(s string) {
|
||||
cs := C.CString(s)
|
||||
C.pango_layout_set_text(v.GLayout, cs, -1)
|
||||
C.free(unsafe.Pointer(cs))
|
||||
}
|
||||
|
||||
func NewLayout(ctx *Context) *Layout {
|
||||
return &Layout{C.pango_layout_new(ctx.GContext)}
|
||||
}
|
||||
|
||||
func NewFontDescription() *FontDescription {
|
||||
return &FontDescription{C.pango_font_description_new()}
|
||||
}
|
||||
|
||||
func (v *FontDescription) Free() {
|
||||
C.pango_font_description_free(v.GFontDescription)
|
||||
}
|
||||
|
||||
func (v *FontDescription) SetSize(size int) {
|
||||
C.pango_font_description_set_size(v.GFontDescription, C.gint(size))
|
||||
}
|
||||
|
||||
func (v *FontDescription) Copy() *FontDescription {
|
||||
return &FontDescription{C.pango_font_description_copy(v.GFontDescription)}
|
||||
}
|
||||
|
||||
func (f *FontDescription) GetSize() int {
|
||||
return int(C.pango_font_description_get_size(f.GFontDescription))
|
||||
}
|
23
vendor/github.com/mattn/go-gtk/pango/pango.go.h
generated
vendored
Normal file
23
vendor/github.com/mattn/go-gtk/pango/pango.go.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef GO_PANGO_H
|
||||
#define GO_PANGO_H
|
||||
|
||||
#ifndef uintptr
|
||||
#define uintptr unsigned int*
|
||||
#endif
|
||||
#include <pango/pango.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
//static const gchar* to_gcharptr(const char* s) { return (const gchar*)s; }
|
||||
//static guchar* to_gucharptr(void* s) { return (guchar*)s; }
|
||||
|
||||
//static void free_string(char* s) { free(s); }
|
||||
|
||||
//static gchar* to_gcharptr(char* s) { return (gchar*)s; }
|
||||
|
||||
//static void free_string(char* s) { free(s); }
|
||||
|
||||
#endif
|
106
vendor/github.com/mattn/go-gtk/tools/gogtkinfo/gogtkinfo.go
generated
vendored
Normal file
106
vendor/github.com/mattn/go-gtk/tools/gogtkinfo/gogtkinfo.go
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Simple tool to approximatively count the progress of go-gtk library.
|
||||
Counts line starting by "func" (binding done) or starting by "//" and containing "gtk_" (binding to do) for each section (starting by a "// text" comment preceded by a "//------------")
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := make([]string, 0, 100)
|
||||
alphabeticalOrder := flag.Bool("a", false, "alphabetical order")
|
||||
githubCode := flag.Bool("g", false, "prepend spaces to each line so github will format them as code")
|
||||
flag.Parse()
|
||||
fname := flag.Arg(0)
|
||||
if fname == "" {
|
||||
fmt.Println("Usage: gogtkinfo [-ag] file")
|
||||
return
|
||||
}
|
||||
file, err := os.Open(fname)
|
||||
if err != nil {
|
||||
log.Print(err.Error())
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
rd := bufio.NewReader(file)
|
||||
var currentSection, sectionAlertName string
|
||||
var cDone, cTodo, p, tDone, tTodo int
|
||||
var sectionAlert, falseAlarm bool
|
||||
for {
|
||||
var l string
|
||||
if falseAlarm {
|
||||
falseAlarm = false
|
||||
} else {
|
||||
line, isPrefix, err := rd.ReadLine()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if isPrefix {
|
||||
return
|
||||
}
|
||||
l = string(line)
|
||||
}
|
||||
if strings.HasPrefix(l, "//---------------") {
|
||||
if sectionAlertName == "" {
|
||||
sectionAlert = true
|
||||
} else {
|
||||
if currentSection != "" {
|
||||
cTot := cDone + cTodo
|
||||
if cTot == 0 {
|
||||
p = 100
|
||||
} else {
|
||||
p = 100 * cDone / cTot
|
||||
}
|
||||
s := fmt.Sprintf("%-30s: %3d%% (%3d/%3d)\n", currentSection, p, cDone, cTot)
|
||||
list = append(list, s)
|
||||
}
|
||||
currentSection = sectionAlertName
|
||||
tDone += cDone
|
||||
tTodo += cTodo
|
||||
cDone = 0
|
||||
cTodo = 0
|
||||
sectionAlertName = ""
|
||||
}
|
||||
} else if sectionAlert {
|
||||
if strings.HasPrefix(l, "//") && len(l) > 3 && !strings.Contains(l, "gtk_") {
|
||||
sectionAlertName = strings.TrimSpace(l[2:len(l)])
|
||||
} else {
|
||||
falseAlarm = true
|
||||
}
|
||||
sectionAlert = false
|
||||
} else if strings.HasPrefix(l, "func") {
|
||||
cDone++
|
||||
} else if strings.HasPrefix(l, "//") && strings.Contains(l, "gtk_") {
|
||||
cTodo++
|
||||
}
|
||||
}
|
||||
if *alphabeticalOrder {
|
||||
sort.StringSlice(list).Sort()
|
||||
}
|
||||
for _, s := range list {
|
||||
if *githubCode {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
fmt.Print(s)
|
||||
}
|
||||
tTot := tDone + tTodo
|
||||
if tTot == 0 {
|
||||
p = 0
|
||||
} else {
|
||||
p = 100 * tDone / tTot
|
||||
}
|
||||
if *githubCode {
|
||||
fmt.Print("\n ")
|
||||
} else {
|
||||
fmt.Print("\n")
|
||||
}
|
||||
fmt.Printf("Total progress : %18d%% (%d/%d)\n", p, tDone, tTot)
|
||||
}
|
29
vendor/github.com/mattn/go-pointer/README.md
generated
vendored
Normal file
29
vendor/github.com/mattn/go-pointer/README.md
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
# go-pointer
|
||||
|
||||
Utility for cgo
|
||||
|
||||
## Usage
|
||||
|
||||
https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
|
||||
|
||||
In go 1.6, cgo argument can't be passed Go pointer.
|
||||
|
||||
```
|
||||
var s string
|
||||
C.pass_pointer(pointer.Save(&s))
|
||||
v := *(pointer.Restore(C.get_from_pointer()).(*string))
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
go get github.com/mattn/go-pointer
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
9
vendor/github.com/mattn/go-pointer/_example/callback.h
generated
vendored
Normal file
9
vendor/github.com/mattn/go-pointer/_example/callback.h
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
typedef void (*callback)(void*);
|
||||
|
||||
static void call_later(int delay, callback cb, void* data) {
|
||||
sleep(delay);
|
||||
cb(data);
|
||||
}
|
||||
|
29
vendor/github.com/mattn/go-pointer/_example/main.go
generated
vendored
Normal file
29
vendor/github.com/mattn/go-pointer/_example/main.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#include "callback.h"
|
||||
|
||||
void call_later_go_cb(void*);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
type Foo struct {
|
||||
v int
|
||||
}
|
||||
|
||||
func main() {
|
||||
f := &Foo{123}
|
||||
C.call_later(3, C.callback(C.call_later_go_cb), pointer.Save(f))
|
||||
}
|
||||
|
||||
//export call_later_go_cb
|
||||
func call_later_go_cb(data unsafe.Pointer) {
|
||||
f := pointer.Restore(data).(*Foo)
|
||||
fmt.Println(f.v)
|
||||
}
|
13
vendor/github.com/mattn/go-pointer/example/example.go
generated
vendored
Normal file
13
vendor/github.com/mattn/go-pointer/example/example.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package example
|
||||
|
||||
/*
|
||||
void *pass_pointer(void* p) {
|
||||
return p;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func PassPointer(ptr unsafe.Pointer) unsafe.Pointer {
|
||||
return C.pass_pointer(ptr)
|
||||
}
|
59
vendor/github.com/mattn/go-pointer/pointer.go
generated
vendored
Normal file
59
vendor/github.com/mattn/go-pointer/pointer.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package pointer
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
mutex sync.Mutex
|
||||
store = map[unsafe.Pointer]interface{}{}
|
||||
)
|
||||
|
||||
func Save(v interface{}) unsafe.Pointer {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate real fake C pointer.
|
||||
// This pointer will not store any data, but will bi used for indexing purposes.
|
||||
// Since Go doest allow to cast dangling pointer to unsafe.Pointer, we do rally allocate one byte.
|
||||
// Why we need indexing, because Go doest allow C code to store pointers to Go data.
|
||||
var ptr unsafe.Pointer = C.malloc(C.size_t(1))
|
||||
if ptr == nil {
|
||||
panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil")
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
store[ptr] = v
|
||||
mutex.Unlock()
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
func Restore(ptr unsafe.Pointer) interface{} {
|
||||
if ptr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if v, ok := store[ptr]; ok {
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Unref(ptr unsafe.Pointer) {
|
||||
if ptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
delete(store, ptr)
|
||||
mutex.Unlock()
|
||||
|
||||
C.free(ptr)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user