summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace')
-rw-r--r--Godeps/_workspace/.gitignore2
-rw-r--r--Godeps/_workspace/src/github.com/NYTimes/gziphandler/LICENSE.md13
-rw-r--r--Godeps/_workspace/src/github.com/NYTimes/gziphandler/README.md52
-rw-r--r--Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go140
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore2
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE13
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/README12
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/config.go288
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go14
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go57
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go42
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go18
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go13
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml47
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go264
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go484
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go126
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go57
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go49
-rw-r--r--Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go278
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/LICENSE19
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/README.md36
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/interfaces.go7
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/server.go272
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/static.go35
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/test_helpers/certs.go29
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/test_helpers/conn.go13
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/test_helpers/listener.go34
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/test_helpers/temp_file.go27
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/test_helpers/wait_group.go33
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/.travis.yml11
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/LICENSE201
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/README.md44
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/ci/scripts/windows-64-test.bat5
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber.go22
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_unix.go57
-rw-r--r--Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_windows.go114
-rw-r--r--Godeps/_workspace/src/github.com/dgryski/dgoogauth/.travis.yml1
-rw-r--r--Godeps/_workspace/src/github.com/dgryski/dgoogauth/README.md15
-rw-r--r--Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth.go199
-rw-r--r--Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth_test.go251
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE21
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/README.md194
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go200
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/effects.go187
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go400
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/resize.go583
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/tools.go182
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/transform.go201
-rw-r--r--Godeps/_workspace/src/github.com/disintegration/imaging/utils.go77
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/LICENSE175
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go54
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/internal/redistest/testdb.go68
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn.go567
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/doc.go169
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/log.go117
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool.go393
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub.go144
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go44
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply.go393
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan.go555
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/script.go86
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/.gitignore8
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/.travis.yml28
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/LICENSE22
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/README.md745
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/column.go83
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/db.go619
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect.go111
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_mysql.go171
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_oracle.go146
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_postgres.go147
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlite.go119
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlserver.go152
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/errors.go38
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/gorp.go558
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/hooks.go49
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/index.go56
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/lockerror.go63
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/logging.go44
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/nulltypes.go58
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/select.go351
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/table.go247
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/table_bindings.go317
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/test_all.sh38
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/transaction.go193
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/.gitignore0
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/.travis.yml15
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/LICENSE27
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/README.md55
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/add.go104
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/bind.go135
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/client.go23
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/compare.go85
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/conn.go369
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/control.go332
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/debug.go24
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/del.go79
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/dn.go155
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/doc.go4
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/error.go137
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/filter.go456
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/ldap.go286
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/modify.go156
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/passwdmodify.go137
-rw-r--r--Godeps/_workspace/src/github.com/go-ldap/ldap/search.go403
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore8
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml10
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS46
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/CHANGELOG.md92
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/CONTRIBUTING.md40
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/LICENSE373
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md386
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go19
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/buffer.go136
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/collations.go250
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/connection.go403
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/const.go162
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/driver.go149
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/errors.go131
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/infile.go182
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go1182
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go22
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/rows.go106
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/statement.go150
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go31
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/utils.go973
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/LICENSE185
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt.go74
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/aws/aws.go432
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/aws/client.go124
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/aws/regions.go254
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/aws/sign.go357
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/s3/multi.go439
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/s3/s3.go1155
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/s3/s3test/server.go633
-rw-r--r--Godeps/_workspace/src/github.com/goamz/goamz/s3/sign.go141
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/AUTHORS18
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/CONTRIBUTORS36
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/LICENSE12
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/README21
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/cmd/print-glyph-points/main.c87
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/drawer/main.go157
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/freetype/main.go149
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/gamma/main.go85
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/raster/main.go184
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/round/main.go109
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/example/truetype/main.go80
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/freetype.go341
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/licenses/ftl.txt169
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/licenses/gpl.txt340
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/raster/geom.go245
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/raster/paint.go287
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/raster/raster.go601
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/raster/stroke.go483
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/face.go495
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/glyph.go517
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/hint.go1763
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/opcodes.go289
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype.go639
-rw-r--r--Godeps/_workspace/src/github.com/golang/groupcache/LICENSE191
-rw-r--r--Godeps/_workspace/src/github.com/golang/groupcache/lru/lru.go121
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/.travis.yml8
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/LICENSE27
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/README.md7
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/context.go143
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/doc.go82
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml17
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE22
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/README.md53
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go74
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/compress.go145
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/cors.go317
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/doc.go9
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go403
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go113
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go86
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml14
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/LICENSE27
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/README.md235
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/doc.go206
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/mux.go474
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/regexp.go317
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/route.go595
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore22
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml6
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS8
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE22
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/README.md61
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/client.go341
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/conn.go831
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/doc.go151
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md13
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json14
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go246
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md20
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go102
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html92
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go51
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go39
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md19
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html96
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go188
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md17
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go81
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go132
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md9
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go193
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/json.go55
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/server.go250
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/util.go44
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/.gitignore4
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/.travis.yml69
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/CONTRIBUTING.md29
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/LICENSE.md8
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/README.md103
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/buf.go91
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/README3
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.crt69
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.key15
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/root.crt24
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/server.crt81
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/certs/server.key27
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/conn.go1777
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/copy.go267
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/doc.go210
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/encode.go538
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/error.go508
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/hstore/hstore.go118
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go102
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/notify.go766
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/oid/doc.go6
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/oid/gen.go74
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/oid/types.go161
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/url.go76
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/user_posix.go24
-rw-r--r--Godeps/_workspace/src/github.com/lib/pq/user_windows.go27
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/gf256/Makefile8
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/gf256/blog_test.go85
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256.go241
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256_test.go194
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/Makefile4
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/Makefile7
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/gen.go149
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go815
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr_test.go133
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/Makefile4
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/qrencode.go149
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go400
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/png_test.go73
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/qr.go116
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/pic.go506
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/play.go1118
-rw-r--r--Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/resize/resize.go152
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/.travis.yml12
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/LICENSE20
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/README.md51
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/bot.go122
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/browser.go129
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/operating_systems.go260
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/user_agent.go169
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/LICENSE19
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go315
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/i18n.go152
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/language.go99
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/operands.go119
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/plural.go40
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec.go74
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec_gen.go567
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go78
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go57
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/template.go61
-rw-r--r--Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/translation.go83
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS1
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/LICENSE27
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/dce.go84
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/doc.go8
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/hash.go53
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/json.go30
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/node.go101
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/sql.go48
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/time.go132
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/util.go43
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/uuid.go163
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/version1.go41
-rw-r--r--Godeps/_workspace/src/github.com/pborman/uuid/version4.go25
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/LICENSE24
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/README.md4
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/huge_tag_exif.jpgbin65536 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/infinite_loop_exif.jpgbin3738 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/max_uint32_exif.jpgbin65536 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/exif.go619
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/fields.go293
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/regen_regress.go79
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/sample1.jpgbin80603 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2004-01-11-22-45-15-sep-2004-01-11-22-45-15a.jpgbin4586 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-08-03-16-29-38-sep-2006-08-03-16-29-38a.jpgbin9735 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-11-11-19-17-56-sep-2006-11-11-19-17-56a.jpgbin35406 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-10-23-58-20-sep-2006-12-10-23-58-20a.jpgbin8711 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-17-07-09-14-sep-2006-12-17-07-09-14a.jpgbin38252 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-21-15-55-26-sep-2006-12-21-15-55-26a.jpgbin16072 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-01-12-00-00-sep-2007-01-01-12-00-00a.jpgbin17301 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-17-21-49-44-sep-2007-01-17-21-49-44a.jpgbin7999 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-02-02-18-13-29-sep-2007-02-02-18-13-29a.jpgbin39915 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-02-17-02-21-sep-2007-05-02-17-02-21a.jpgbin11783 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-12-08-19-07-sep-2007-05-12-08-19-07a.jpgbin35771 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-26-04-49-45-sep-2007-05-26-04-49-45a.jpgbin35406 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-30-14-28-01-sep-2007-05-30-14-28-01a.jpgbin35406 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-06-16-15-25-sep-2007-06-06-16-15-25a.jpgbin35406 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-26-10-13-04-sep-2007-06-26-10-13-04a.jpgbin7615 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-07-13-17-02-30-sep-2007-07-13-17-02-30a.jpgbin21719 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-15-14-42-46-sep-2007-08-15-14-42-46a.jpgbin11549 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-24-02-40-42-sep-2007-08-24-02-40-42a.jpgbin7687 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-11-07-11-40-44-sep-2007-11-07-11-40-44a.jpgbin11223 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-02-10-03-57-sep-2008-06-02-10-03-57a.jpgbin9745 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-06-13-29-29-sep-2008-06-06-13-29-29a.jpgbin11783 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-17-01-21-30-sep-2008-06-17-01-21-30a.jpgbin14564 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-09-02-17-43-48-sep-2008-09-02-17-43-48a.jpgbin5406 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-03-26-09-23-20-sep-2009-03-26-09-23-20a.jpgbin10759 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-11-03-01-38-sep-2009-04-11-03-01-38a.jpgbin43374 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-23-07-21-35-sep-2009-04-23-07-21-35a.jpgbin37208 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-11-19-23-18-sep-2009-06-11-19-23-18a.jpgbin7791 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-20-07-59-05-sep-2009-06-20-07-59-05a.jpgbin13618 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-08-05-08-11-31-sep-2009-08-05-08-11-31a.jpgbin9919 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-08-04-44-24-sep-2010-06-08-04-44-24a.jpgbin10939 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-20-20-07-39-sep-2010-06-20-20-07-39a.jpgbin8551 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-09-02-08-43-02-sep-2010-09-02-08-43-02a.jpgbin19534 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-01-24-22-06-02-sep-2011-01-24-22-06-02a.jpgbin29003 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-03-07-09-28-03-sep-2011-03-07-09-28-03a.jpgbin10529 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-05-07-13-02-49-sep-2011-05-07-13-02-49a.jpgbin23743 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-08-07-19-22-57-sep-2011-08-07-19-22-57a.jpgbin9936 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-17-50-18-sep-2011-10-28-17-50-18a.jpgbin7487 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-18-25-43-sep-2011-10-28-18-25-43.jpgbin7433 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-11-18-15-38-34-sep-Photo11181538.jpgbin12885 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-06-02-10-12-28-sep-2012-06-02-10-12-28.jpgbin32165 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-09-21-22-07-34-sep-2012-09-21-22-07-34.jpgbin10247 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-19-21-38-40-sep-temple_square1.jpgbin39182 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-21-11-15-19-sep-IMG_0001.jpgbin25269 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2013-02-05-23-12-09-sep-DSCI0001.jpgbin10854 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2099-08-12-19-59-29-sep-2099-08-12-19-59-29a.jpgbin37491 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2216-11-15-11-46-51-sep-2216-11-15-11-46-51a.jpgbin23011 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/FailedHash-NoDate-sep-remembory.jpgbin935 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f1-exif.jpgbin992 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f2-exif.jpgbin994 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f3-exif.jpgbin992 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f4-exif.jpgbin994 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f5-exif.jpgbin980 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f6-exif.jpgbin982 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f7-exif.jpgbin980 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f8-exif.jpgbin982 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/geodegrees_as_string.jpgbin22420 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/has-lens-info.jpgbin22493 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/sample1.tifbin18382 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tag.go438
-rw-r--r--Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tiff.go153
-rw-r--r--Godeps/_workspace/src/github.com/vaughan0/go-ini/LICENSE14
-rw-r--r--Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md70
-rw-r--r--Godeps/_workspace/src/github.com/vaughan0/go-ini/ini.go123
-rw-r--r--Godeps/_workspace/src/github.com/vaughan0/go-ini/test.ini2
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/LICENSE27
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/PATENTS22
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go35
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go294
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go159
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go91
-rw-r--r--Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go199
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/LICENSE27
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/PATENTS22
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/bmp/reader.go199
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/bmp/writer.go166
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/font/basicfont/basicfont.go113
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/font/basicfont/data.go1456
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/font/basicfont/gen.go115
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/font/font.go202
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/font/plan9font/plan9font.go556
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/math/fixed/fixed.go172
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/buffer.go69
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/compress.go58
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/consts.go133
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/lzw/reader.go277
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/reader.go681
-rw-r--r--Godeps/_workspace/src/golang.org/x/image/tiff/writer.go438
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml15
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE27
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md24
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go504
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go25
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go29
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go103
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go71
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.berbin11 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.berbin7 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.berbin11 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.berbin5 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.berbin5 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.berbin3 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.berbin5 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.berbin4 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.berbin2 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.berbin16 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.berbin20 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.berbin14 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.berbin16 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.berbin2 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.berbin2 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.berbin16 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.berbin14 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.berbin2 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.berbin2 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.berbin11 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.berbin16 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.berbin16 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.berbin5 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go24
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/.gitignore6
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/.travis.yml20
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/AUTHORS39
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/CHANGELOG.md274
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/CONTRIBUTING.md77
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/LICENSE28
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md64
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/fsnotify.go62
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify.go324
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify_poller.go186
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go481
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_bsd.go11
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_darwin.go12
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/windows.go561
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.gitignore10
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.travis.yml10
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/LICENSE12
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/README.md82
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/delayer.go109
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/doc.go77
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/README.md12
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/custom/main.go90
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-many/main.go79
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/main.go74
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/siege-urls4
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval/main.go69
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/main.go97
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/test-filebin65536 -> 0 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/rate-limit/main.go101
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/interval.go164
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/memstats.go214
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/misc/pre-commit38
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go116
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store.go31
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/doc.go2
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/mem.go90
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/redis.go85
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/throttler.go86
-rw-r--r--Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/varyby.go78
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE188
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml31
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/README.md131
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/apic.go742
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go683
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/emitterc.go1685
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/encode.go306
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/parserc.go1096
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/readerc.go394
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/resolve.go203
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/scannerc.go2710
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/sorter.go104
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/writerc.go89
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/yaml.go346
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/yamlh.go716
-rw-r--r--Godeps/_workspace/src/gopkg.in/yaml.v2/yamlprivateh.go173
494 files changed, 0 insertions, 72255 deletions
diff --git a/Godeps/_workspace/.gitignore b/Godeps/_workspace/.gitignore
deleted file mode 100644
index f037d684e..000000000
--- a/Godeps/_workspace/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/pkg
-/bin
diff --git a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/LICENSE.md b/Godeps/_workspace/src/github.com/NYTimes/gziphandler/LICENSE.md
deleted file mode 100644
index b7e2ecb63..000000000
--- a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/LICENSE.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2015 The New York Times Company
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this library 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.
diff --git a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/README.md b/Godeps/_workspace/src/github.com/NYTimes/gziphandler/README.md
deleted file mode 100644
index b1d55e26e..000000000
--- a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-Gzip Handler
-============
-
-This is a tiny Go package which wraps HTTP handlers to transparently gzip the
-response body, for clients which support it. Although it's usually simpler to
-leave that to a reverse proxy (like nginx or Varnish), this package is useful
-when that's undesirable.
-
-
-## Usage
-
-Call `GzipHandler` with any handler (an object which implements the
-`http.Handler` interface), and it'll return a new handler which gzips the
-response. For example:
-
-```go
-package main
-
-import (
- "io"
- "net/http"
- "github.com/NYTimes/gziphandler"
-)
-
-func main() {
- withoutGz := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/plain")
- io.WriteString(w, "Hello, World")
- })
-
- withGz := gziphandler.GzipHandler(withoutGz)
-
- http.Handle("/", withGz)
- http.ListenAndServe("0.0.0.0:8000", nil)
-}
-```
-
-
-## Documentation
-
-The docs can be found at [godoc.org] [docs], as usual.
-
-
-## License
-
-[Apache 2.0] [license].
-
-
-
-
-[docs]: https://godoc.org/github.com/nytimes/gziphandler
-[license]: https://github.com/nytimes/gziphandler/blob/master/LICENSE.md
diff --git a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go b/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go
deleted file mode 100644
index d0c85c6d3..000000000
--- a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go
+++ /dev/null
@@ -1,140 +0,0 @@
-package gziphandler
-
-import (
- "compress/gzip"
- "fmt"
- "net/http"
- "strconv"
- "strings"
- "sync"
-)
-
-const (
- vary = "Vary"
- acceptEncoding = "Accept-Encoding"
- contentEncoding = "Content-Encoding"
-)
-
-type codings map[string]float64
-
-// The default qvalue to assign to an encoding if no explicit qvalue is set.
-// This is actually kind of ambiguous in RFC 2616, so hopefully it's correct.
-// The examples seem to indicate that it is.
-const DEFAULT_QVALUE = 1.0
-
-var gzipWriterPool = sync.Pool{
- New: func() interface{} { return gzip.NewWriter(nil) },
-}
-
-// GzipResponseWriter provides an http.ResponseWriter interface, which gzips
-// bytes before writing them to the underlying response. This doesn't set the
-// Content-Encoding header, nor close the writers, so don't forget to do that.
-type GzipResponseWriter struct {
- gw *gzip.Writer
- http.ResponseWriter
-}
-
-// Write appends data to the gzip writer.
-func (w GzipResponseWriter) Write(b []byte) (int, error) {
- return w.gw.Write(b)
-}
-
-// Flush flushes the underlying *gzip.Writer and then the underlying
-// http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter
-// an http.Flusher.
-func (w GzipResponseWriter) Flush() {
- w.gw.Flush()
- if fw, ok := w.ResponseWriter.(http.Flusher); ok {
- fw.Flush()
- }
-}
-
-// GzipHandler wraps an HTTP handler, to transparently gzip the response body if
-// the client supports it (via the Accept-Encoding header).
-func GzipHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Add(vary, acceptEncoding)
-
- if acceptsGzip(r) {
- // Bytes written during ServeHTTP are redirected to this gzip writer
- // before being written to the underlying response.
- gzw := gzipWriterPool.Get().(*gzip.Writer)
- defer gzipWriterPool.Put(gzw)
- gzw.Reset(w)
- defer gzw.Close()
-
- w.Header().Set(contentEncoding, "gzip")
- h.ServeHTTP(GzipResponseWriter{gzw, w}, r)
- } else {
- h.ServeHTTP(w, r)
- }
- })
-}
-
-// acceptsGzip returns true if the given HTTP request indicates that it will
-// accept a gzippped response.
-func acceptsGzip(r *http.Request) bool {
- acceptedEncodings, _ := parseEncodings(r.Header.Get(acceptEncoding))
- return acceptedEncodings["gzip"] > 0.0
-}
-
-// parseEncodings attempts to parse a list of codings, per RFC 2616, as might
-// appear in an Accept-Encoding header. It returns a map of content-codings to
-// quality values, and an error containing the errors encounted. It's probably
-// safe to ignore those, because silently ignoring errors is how the internet
-// works.
-//
-// See: http://tools.ietf.org/html/rfc2616#section-14.3
-func parseEncodings(s string) (codings, error) {
- c := make(codings)
- e := make([]string, 0)
-
- for _, ss := range strings.Split(s, ",") {
- coding, qvalue, err := parseCoding(ss)
-
- if err != nil {
- e = append(e, err.Error())
-
- } else {
- c[coding] = qvalue
- }
- }
-
- // TODO (adammck): Use a proper multi-error struct, so the individual errors
- // can be extracted if anyone cares.
- if len(e) > 0 {
- return c, fmt.Errorf("errors while parsing encodings: %s", strings.Join(e, ", "))
- }
-
- return c, nil
-}
-
-// parseCoding parses a single conding (content-coding with an optional qvalue),
-// as might appear in an Accept-Encoding header. It attempts to forgive minor
-// formatting errors.
-func parseCoding(s string) (coding string, qvalue float64, err error) {
- for n, part := range strings.Split(s, ";") {
- part = strings.TrimSpace(part)
- qvalue = DEFAULT_QVALUE
-
- if n == 0 {
- coding = strings.ToLower(part)
-
- } else if strings.HasPrefix(part, "q=") {
- qvalue, err = strconv.ParseFloat(strings.TrimPrefix(part, "q="), 64)
-
- if qvalue < 0.0 {
- qvalue = 0.0
-
- } else if qvalue > 1.0 {
- qvalue = 1.0
- }
- }
- }
-
- if coding == "" {
- err = fmt.Errorf("empty content-coding")
- }
-
- return
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore b/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore
deleted file mode 100644
index f6207cd8a..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.sw[op]
-.DS_Store
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE b/Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE
deleted file mode 100644
index 7093402bf..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/README b/Godeps/_workspace/src/github.com/alecthomas/log4go/README
deleted file mode 100644
index 16d80ecb7..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/README
+++ /dev/null
@@ -1,12 +0,0 @@
-Please see http://log4go.googlecode.com/
-
-Installation:
-- Run `goinstall log4go.googlecode.com/hg`
-
-Usage:
-- Add the following import:
-import l4g "log4go.googlecode.com/hg"
-
-Acknowledgements:
-- pomack
- For providing awesome patches to bring log4go up to the latest Go spec
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/config.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/config.go
deleted file mode 100644
index 577c3eb2f..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/config.go
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "encoding/xml"
- "fmt"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
-)
-
-type xmlProperty struct {
- Name string `xml:"name,attr"`
- Value string `xml:",chardata"`
-}
-
-type xmlFilter struct {
- Enabled string `xml:"enabled,attr"`
- Tag string `xml:"tag"`
- Level string `xml:"level"`
- Type string `xml:"type"`
- Property []xmlProperty `xml:"property"`
-}
-
-type xmlLoggerConfig struct {
- Filter []xmlFilter `xml:"filter"`
-}
-
-// Load XML configuration; see examples/example.xml for documentation
-func (log Logger) LoadConfiguration(filename string) {
- log.Close()
-
- // Open the configuration file
- fd, err := os.Open(filename)
- if err != nil {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Could not open %q for reading: %s\n", filename, err)
- os.Exit(1)
- }
-
- contents, err := ioutil.ReadAll(fd)
- if err != nil {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Could not read %q: %s\n", filename, err)
- os.Exit(1)
- }
-
- xc := new(xmlLoggerConfig)
- if err := xml.Unmarshal(contents, xc); err != nil {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Could not parse XML configuration in %q: %s\n", filename, err)
- os.Exit(1)
- }
-
- for _, xmlfilt := range xc.Filter {
- var filt LogWriter
- var lvl Level
- bad, good, enabled := false, true, false
-
- // Check required children
- if len(xmlfilt.Enabled) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required attribute %s for filter missing in %s\n", "enabled", filename)
- bad = true
- } else {
- enabled = xmlfilt.Enabled != "false"
- }
- if len(xmlfilt.Tag) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required child <%s> for filter missing in %s\n", "tag", filename)
- bad = true
- }
- if len(xmlfilt.Type) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required child <%s> for filter missing in %s\n", "type", filename)
- bad = true
- }
- if len(xmlfilt.Level) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required child <%s> for filter missing in %s\n", "level", filename)
- bad = true
- }
-
- switch xmlfilt.Level {
- case "FINEST":
- lvl = FINEST
- case "FINE":
- lvl = FINE
- case "DEBUG":
- lvl = DEBUG
- case "TRACE":
- lvl = TRACE
- case "INFO":
- lvl = INFO
- case "WARNING":
- lvl = WARNING
- case "ERROR":
- lvl = ERROR
- case "CRITICAL":
- lvl = CRITICAL
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required child <%s> for filter has unknown value in %s: %s\n", "level", filename, xmlfilt.Level)
- bad = true
- }
-
- // Just so all of the required attributes are errored at the same time if missing
- if bad {
- os.Exit(1)
- }
-
- switch xmlfilt.Type {
- case "console":
- filt, good = xmlToConsoleLogWriter(filename, xmlfilt.Property, enabled)
- case "file":
- filt, good = xmlToFileLogWriter(filename, xmlfilt.Property, enabled)
- case "xml":
- filt, good = xmlToXMLLogWriter(filename, xmlfilt.Property, enabled)
- case "socket":
- filt, good = xmlToSocketLogWriter(filename, xmlfilt.Property, enabled)
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Could not load XML configuration in %s: unknown filter type \"%s\"\n", filename, xmlfilt.Type)
- os.Exit(1)
- }
-
- // Just so all of the required params are errored at the same time if wrong
- if !good {
- os.Exit(1)
- }
-
- // If we're disabled (syntax and correctness checks only), don't add to logger
- if !enabled {
- continue
- }
-
- log[xmlfilt.Tag] = &Filter{lvl, filt}
- }
-}
-
-func xmlToConsoleLogWriter(filename string, props []xmlProperty, enabled bool) (*ConsoleLogWriter, bool) {
- // Parse properties
- for _, prop := range props {
- switch prop.Name {
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Warning: Unknown property \"%s\" for console filter in %s\n", prop.Name, filename)
- }
- }
-
- // If it's disabled, we're just checking syntax
- if !enabled {
- return nil, true
- }
-
- return NewConsoleLogWriter(), true
-}
-
-// Parse a number with K/M/G suffixes based on thousands (1000) or 2^10 (1024)
-func strToNumSuffix(str string, mult int) int {
- num := 1
- if len(str) > 1 {
- switch str[len(str)-1] {
- case 'G', 'g':
- num *= mult
- fallthrough
- case 'M', 'm':
- num *= mult
- fallthrough
- case 'K', 'k':
- num *= mult
- str = str[0 : len(str)-1]
- }
- }
- parsed, _ := strconv.Atoi(str)
- return parsed * num
-}
-func xmlToFileLogWriter(filename string, props []xmlProperty, enabled bool) (*FileLogWriter, bool) {
- file := ""
- format := "[%D %T] [%L] (%S) %M"
- maxlines := 0
- maxsize := 0
- daily := false
- rotate := false
-
- // Parse properties
- for _, prop := range props {
- switch prop.Name {
- case "filename":
- file = strings.Trim(prop.Value, " \r\n")
- case "format":
- format = strings.Trim(prop.Value, " \r\n")
- case "maxlines":
- maxlines = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1000)
- case "maxsize":
- maxsize = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1024)
- case "daily":
- daily = strings.Trim(prop.Value, " \r\n") != "false"
- case "rotate":
- rotate = strings.Trim(prop.Value, " \r\n") != "false"
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Warning: Unknown property \"%s\" for file filter in %s\n", prop.Name, filename)
- }
- }
-
- // Check properties
- if len(file) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required property \"%s\" for file filter missing in %s\n", "filename", filename)
- return nil, false
- }
-
- // If it's disabled, we're just checking syntax
- if !enabled {
- return nil, true
- }
-
- flw := NewFileLogWriter(file, rotate)
- flw.SetFormat(format)
- flw.SetRotateLines(maxlines)
- flw.SetRotateSize(maxsize)
- flw.SetRotateDaily(daily)
- return flw, true
-}
-
-func xmlToXMLLogWriter(filename string, props []xmlProperty, enabled bool) (*FileLogWriter, bool) {
- file := ""
- maxrecords := 0
- maxsize := 0
- daily := false
- rotate := false
-
- // Parse properties
- for _, prop := range props {
- switch prop.Name {
- case "filename":
- file = strings.Trim(prop.Value, " \r\n")
- case "maxrecords":
- maxrecords = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1000)
- case "maxsize":
- maxsize = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1024)
- case "daily":
- daily = strings.Trim(prop.Value, " \r\n") != "false"
- case "rotate":
- rotate = strings.Trim(prop.Value, " \r\n") != "false"
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Warning: Unknown property \"%s\" for xml filter in %s\n", prop.Name, filename)
- }
- }
-
- // Check properties
- if len(file) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required property \"%s\" for xml filter missing in %s\n", "filename", filename)
- return nil, false
- }
-
- // If it's disabled, we're just checking syntax
- if !enabled {
- return nil, true
- }
-
- xlw := NewXMLLogWriter(file, rotate)
- xlw.SetRotateLines(maxrecords)
- xlw.SetRotateSize(maxsize)
- xlw.SetRotateDaily(daily)
- return xlw, true
-}
-
-func xmlToSocketLogWriter(filename string, props []xmlProperty, enabled bool) (SocketLogWriter, bool) {
- endpoint := ""
- protocol := "udp"
-
- // Parse properties
- for _, prop := range props {
- switch prop.Name {
- case "endpoint":
- endpoint = strings.Trim(prop.Value, " \r\n")
- case "protocol":
- protocol = strings.Trim(prop.Value, " \r\n")
- default:
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Warning: Unknown property \"%s\" for file filter in %s\n", prop.Name, filename)
- }
- }
-
- // Check properties
- if len(endpoint) == 0 {
- fmt.Fprintf(os.Stderr, "LoadConfiguration: Error: Required property \"%s\" for file filter missing in %s\n", "endpoint", filename)
- return nil, false
- }
-
- // If it's disabled, we're just checking syntax
- if !enabled {
- return nil, true
- }
-
- return NewSocketLogWriter(protocol, endpoint), true
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go
deleted file mode 100644
index 698dd332d..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package main
-
-import (
- "time"
-)
-
-import l4g "code.google.com/p/log4go"
-
-func main() {
- log := l4g.NewLogger()
- defer log.Close()
- log.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter())
- log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go
deleted file mode 100644
index efd596aa6..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package main
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "time"
-)
-
-import l4g "code.google.com/p/log4go"
-
-const (
- filename = "flw.log"
-)
-
-func main() {
- // Get a new logger instance
- log := l4g.NewLogger()
-
- // Create a default logger that is logging messages of FINE or higher
- log.AddFilter("file", l4g.FINE, l4g.NewFileLogWriter(filename, false))
- log.Close()
-
- /* Can also specify manually via the following: (these are the defaults) */
- flw := l4g.NewFileLogWriter(filename, false)
- flw.SetFormat("[%D %T] [%L] (%S) %M")
- flw.SetRotate(false)
- flw.SetRotateSize(0)
- flw.SetRotateLines(0)
- flw.SetRotateDaily(false)
- log.AddFilter("file", l4g.FINE, flw)
-
- // Log some experimental messages
- log.Finest("Everything is created now (notice that I will not be printing to the file)")
- log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
- log.Critical("Time to close out!")
-
- // Close the log
- log.Close()
-
- // Print what was logged to the file (yes, I know I'm skipping error checking)
- fd, _ := os.Open(filename)
- in := bufio.NewReader(fd)
- fmt.Print("Messages logged to file were: (line numbers not included)\n")
- for lineno := 1; ; lineno++ {
- line, err := in.ReadString('\n')
- if err == io.EOF {
- break
- }
- fmt.Printf("%3d:\t%s", lineno, line)
- }
- fd.Close()
-
- // Remove the file so it's not lying around
- os.Remove(filename)
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go
deleted file mode 100644
index 83c80ad12..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "net"
- "os"
-)
-
-var (
- port = flag.String("p", "12124", "Port number to listen on")
-)
-
-func e(err error) {
- if err != nil {
- fmt.Printf("Erroring out: %s\n", err)
- os.Exit(1)
- }
-}
-
-func main() {
- flag.Parse()
-
- // Bind to the port
- bind, err := net.ResolveUDPAddr("0.0.0.0:" + *port)
- e(err)
-
- // Create listener
- listener, err := net.ListenUDP("udp", bind)
- e(err)
-
- fmt.Printf("Listening to port %s...\n", *port)
- for {
- // read into a new buffer
- buffer := make([]byte, 1024)
- _, _, err := listener.ReadFrom(buffer)
- e(err)
-
- // log to standard output
- fmt.Println(string(buffer))
- }
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go
deleted file mode 100644
index 400b698ca..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package main
-
-import (
- "time"
-)
-
-import l4g "code.google.com/p/log4go"
-
-func main() {
- log := l4g.NewLogger()
- log.AddFilter("network", l4g.FINEST, l4g.NewSocketLogWriter("udp", "192.168.1.255:12124"))
-
- // Run `nc -u -l -p 12124` or similar before you run this to see the following message
- log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
-
- // This makes sure the output stream buffer is written
- log.Close()
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go
deleted file mode 100644
index 164c2add4..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package main
-
-import l4g "code.google.com/p/log4go"
-
-func main() {
- // Load the configuration (isn't this easy?)
- l4g.LoadConfiguration("example.xml")
-
- // And now we're ready!
- l4g.Finest("This will only go to those of you really cool UDP kids! If you change enabled=true.")
- l4g.Debug("Oh no! %d + %d = %d!", 2, 2, 2+2)
- l4g.Info("About that time, eh chaps?")
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml
deleted file mode 100644
index e791278ce..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<logging>
- <filter enabled="true">
- <tag>stdout</tag>
- <type>console</type>
- <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) -->
- <level>DEBUG</level>
- </filter>
- <filter enabled="true">
- <tag>file</tag>
- <type>file</type>
- <level>FINEST</level>
- <property name="filename">test.log</property>
- <!--
- %T - Time (15:04:05 MST)
- %t - Time (15:04)
- %D - Date (2006/01/02)
- %d - Date (01/02/06)
- %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
- %S - Source
- %M - Message
- It ignores unknown format strings (and removes them)
- Recommended: "[%D %T] [%L] (%S) %M"
- -->
- <property name="format">[%D %T] [%L] (%S) %M</property>
- <property name="rotate">false</property> <!-- true enables log rotation, otherwise append -->
- <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
- <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
- <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight -->
- </filter>
- <filter enabled="true">
- <tag>xmllog</tag>
- <type>xml</type>
- <level>TRACE</level>
- <property name="filename">trace.xml</property>
- <property name="rotate">true</property> <!-- true enables log rotation, otherwise append -->
- <property name="maxsize">100M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
- <property name="maxrecords">6K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
- <property name="daily">false</property> <!-- Automatically rotates when a log message is written after midnight -->
- </filter>
- <filter enabled="false"><!-- enabled=false means this logger won't actually be created -->
- <tag>donotopen</tag>
- <type>socket</type>
- <level>FINEST</level>
- <property name="endpoint">192.168.1.255:12124</property> <!-- recommend UDP broadcast -->
- <property name="protocol">udp</property> <!-- tcp or udp -->
- </filter>
-</logging>
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go
deleted file mode 100644
index ee0ab0c04..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "fmt"
- "os"
- "time"
-)
-
-// This log writer sends output to a file
-type FileLogWriter struct {
- rec chan *LogRecord
- rot chan bool
-
- // The opened file
- filename string
- file *os.File
-
- // The logging format
- format string
-
- // File header/trailer
- header, trailer string
-
- // Rotate at linecount
- maxlines int
- maxlines_curlines int
-
- // Rotate at size
- maxsize int
- maxsize_cursize int
-
- // Rotate daily
- daily bool
- daily_opendate int
-
- // Keep old logfiles (.001, .002, etc)
- rotate bool
- maxbackup int
-}
-
-// This is the FileLogWriter's output method
-func (w *FileLogWriter) LogWrite(rec *LogRecord) {
- w.rec <- rec
-}
-
-func (w *FileLogWriter) Close() {
- close(w.rec)
- w.file.Sync()
-}
-
-// NewFileLogWriter creates a new LogWriter which writes to the given file and
-// has rotation enabled if rotate is true.
-//
-// If rotate is true, any time a new log file is opened, the old one is renamed
-// with a .### extension to preserve it. The various Set* methods can be used
-// to configure log rotation based on lines, size, and daily.
-//
-// The standard log-line format is:
-// [%D %T] [%L] (%S) %M
-func NewFileLogWriter(fname string, rotate bool) *FileLogWriter {
- w := &FileLogWriter{
- rec: make(chan *LogRecord, LogBufferLength),
- rot: make(chan bool),
- filename: fname,
- format: "[%D %T] [%L] (%S) %M",
- rotate: rotate,
- maxbackup: 999,
- }
-
- // open the file for the first time
- if err := w.intRotate(); err != nil {
- fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
- return nil
- }
-
- go func() {
- defer func() {
- if w.file != nil {
- fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
- w.file.Close()
- }
- }()
-
- for {
- select {
- case <-w.rot:
- if err := w.intRotate(); err != nil {
- fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
- return
- }
- case rec, ok := <-w.rec:
- if !ok {
- return
- }
- now := time.Now()
- if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
- (w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
- (w.daily && now.Day() != w.daily_opendate) {
- if err := w.intRotate(); err != nil {
- fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
- return
- }
- }
-
- // Perform the write
- n, err := fmt.Fprint(w.file, FormatLogRecord(w.format, rec))
- if err != nil {
- fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
- return
- }
-
- // Update the counts
- w.maxlines_curlines++
- w.maxsize_cursize += n
- }
- }
- }()
-
- return w
-}
-
-// Request that the logs rotate
-func (w *FileLogWriter) Rotate() {
- w.rot <- true
-}
-
-// If this is called in a threaded context, it MUST be synchronized
-func (w *FileLogWriter) intRotate() error {
- // Close any log file that may be open
- if w.file != nil {
- fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
- w.file.Close()
- }
-
- // If we are keeping log files, move it to the next available number
- if w.rotate {
- _, err := os.Lstat(w.filename)
- if err == nil { // file exists
- // Find the next available number
- num := 1
- fname := ""
- if w.daily && time.Now().Day() != w.daily_opendate {
- yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
-
- for ; err == nil && num <= 999; num++ {
- fname = w.filename + fmt.Sprintf(".%s.%03d", yesterday, num)
- _, err = os.Lstat(fname)
- }
- // return error if the last file checked still existed
- if err == nil {
- return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
- }
- } else {
- num = w.maxbackup - 1
- for ; num >= 1; num-- {
- fname = w.filename + fmt.Sprintf(".%d", num)
- nfname := w.filename + fmt.Sprintf(".%d", num+1)
- _, err = os.Lstat(fname)
- if err == nil {
- os.Rename(fname, nfname)
- }
- }
- }
-
- w.file.Close()
- // Rename the file to its newfound home
- err = os.Rename(w.filename, fname)
- if err != nil {
- return fmt.Errorf("Rotate: %s\n", err)
- }
- }
- }
-
- // Open the log file
- fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
- if err != nil {
- return err
- }
- w.file = fd
-
- now := time.Now()
- fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: now}))
-
- // Set the daily open date to the current date
- w.daily_opendate = now.Day()
-
- // initialize rotation values
- w.maxlines_curlines = 0
- w.maxsize_cursize = 0
-
- return nil
-}
-
-// Set the logging format (chainable). Must be called before the first log
-// message is written.
-func (w *FileLogWriter) SetFormat(format string) *FileLogWriter {
- w.format = format
- return w
-}
-
-// Set the logfile header and footer (chainable). Must be called before the first log
-// message is written. These are formatted similar to the FormatLogRecord (e.g.
-// you can use %D and %T in your header/footer for date and time).
-func (w *FileLogWriter) SetHeadFoot(head, foot string) *FileLogWriter {
- w.header, w.trailer = head, foot
- if w.maxlines_curlines == 0 {
- fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: time.Now()}))
- }
- return w
-}
-
-// Set rotate at linecount (chainable). Must be called before the first log
-// message is written.
-func (w *FileLogWriter) SetRotateLines(maxlines int) *FileLogWriter {
- //fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateLines: %v\n", maxlines)
- w.maxlines = maxlines
- return w
-}
-
-// Set rotate at size (chainable). Must be called before the first log message
-// is written.
-func (w *FileLogWriter) SetRotateSize(maxsize int) *FileLogWriter {
- //fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateSize: %v\n", maxsize)
- w.maxsize = maxsize
- return w
-}
-
-// Set rotate daily (chainable). Must be called before the first log message is
-// written.
-func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter {
- //fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateDaily: %v\n", daily)
- w.daily = daily
- return w
-}
-
-// Set max backup files. Must be called before the first log message
-// is written.
-func (w *FileLogWriter) SetRotateMaxBackup(maxbackup int) *FileLogWriter {
- w.maxbackup = maxbackup
- return w
-}
-
-// SetRotate changes whether or not the old logs are kept. (chainable) Must be
-// called before the first log message is written. If rotate is false, the
-// files are overwritten; otherwise, they are rotated to another file before the
-// new log is opened.
-func (w *FileLogWriter) SetRotate(rotate bool) *FileLogWriter {
- //fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotate: %v\n", rotate)
- w.rotate = rotate
- return w
-}
-
-// NewXMLLogWriter is a utility method for creating a FileLogWriter set up to
-// output XML record log messages instead of line-based ones.
-func NewXMLLogWriter(fname string, rotate bool) *FileLogWriter {
- return NewFileLogWriter(fname, rotate).SetFormat(
- ` <record level="%L">
- <timestamp>%D %T</timestamp>
- <source>%S</source>
- <message>%M</message>
- </record>`).SetHeadFoot("<log created=\"%D %T\">", "</log>")
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go
deleted file mode 100644
index 822e890cc..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-// Package log4go provides level-based and highly configurable logging.
-//
-// Enhanced Logging
-//
-// This is inspired by the logging functionality in Java. Essentially, you create a Logger
-// object and create output filters for it. You can send whatever you want to the Logger,
-// and it will filter that based on your settings and send it to the outputs. This way, you
-// can put as much debug code in your program as you want, and when you're done you can filter
-// out the mundane messages so only the important ones show up.
-//
-// Utility functions are provided to make life easier. Here is some example code to get started:
-//
-// log := log4go.NewLogger()
-// log.AddFilter("stdout", log4go.DEBUG, log4go.NewConsoleLogWriter())
-// log.AddFilter("log", log4go.FINE, log4go.NewFileLogWriter("example.log", true))
-// log.Info("The time is now: %s", time.LocalTime().Format("15:04:05 MST 2006/01/02"))
-//
-// The first two lines can be combined with the utility NewDefaultLogger:
-//
-// log := log4go.NewDefaultLogger(log4go.DEBUG)
-// log.AddFilter("log", log4go.FINE, log4go.NewFileLogWriter("example.log", true))
-// log.Info("The time is now: %s", time.LocalTime().Format("15:04:05 MST 2006/01/02"))
-//
-// Usage notes:
-// - The ConsoleLogWriter does not display the source of the message to standard
-// output, but the FileLogWriter does.
-// - The utility functions (Info, Debug, Warn, etc) derive their source from the
-// calling function, and this incurs extra overhead.
-//
-// Changes from 2.0:
-// - The external interface has remained mostly stable, but a lot of the
-// internals have been changed, so if you depended on any of this or created
-// your own LogWriter, then you will probably have to update your code. In
-// particular, Logger is now a map and ConsoleLogWriter is now a channel
-// behind-the-scenes, and the LogWrite method no longer has return values.
-//
-// Future work: (please let me know if you think I should work on any of these particularly)
-// - Log file rotation
-// - Logging configuration files ala log4j
-// - Have the ability to remove filters?
-// - Have GetInfoChannel, GetDebugChannel, etc return a chan string that allows
-// for another method of logging
-// - Add an XML filter type
-package log4go
-
-import (
- "errors"
- "fmt"
- "os"
- "runtime"
- "strings"
- "time"
-)
-
-// Version information
-const (
- L4G_VERSION = "log4go-v3.0.1"
- L4G_MAJOR = 3
- L4G_MINOR = 0
- L4G_BUILD = 1
-)
-
-/****** Constants ******/
-
-// These are the integer logging levels used by the logger
-type Level int
-
-const (
- FINEST Level = iota
- FINE
- DEBUG
- TRACE
- INFO
- WARNING
- ERROR
- CRITICAL
-)
-
-// Logging level strings
-var (
- levelStrings = [...]string{"FNST", "FINE", "DEBG", "TRAC", "INFO", "WARN", "EROR", "CRIT"}
-)
-
-func (l Level) String() string {
- if l < 0 || int(l) > len(levelStrings) {
- return "UNKNOWN"
- }
- return levelStrings[int(l)]
-}
-
-/****** Variables ******/
-var (
- // LogBufferLength specifies how many log messages a particular log4go
- // logger can buffer at a time before writing them.
- LogBufferLength = 32
-)
-
-/****** LogRecord ******/
-
-// A LogRecord contains all of the pertinent information for each message
-type LogRecord struct {
- Level Level // The log level
- Created time.Time // The time at which the log message was created (nanoseconds)
- Source string // The message source
- Message string // The log message
-}
-
-/****** LogWriter ******/
-
-// This is an interface for anything that should be able to write logs
-type LogWriter interface {
- // This will be called to log a LogRecord message.
- LogWrite(rec *LogRecord)
-
- // This should clean up anything lingering about the LogWriter, as it is called before
- // the LogWriter is removed. LogWrite should not be called after Close.
- Close()
-}
-
-/****** Logger ******/
-
-// A Filter represents the log level below which no log records are written to
-// the associated LogWriter.
-type Filter struct {
- Level Level
- LogWriter
-}
-
-// A Logger represents a collection of Filters through which log messages are
-// written.
-type Logger map[string]*Filter
-
-// Create a new logger.
-//
-// DEPRECATED: Use make(Logger) instead.
-func NewLogger() Logger {
- os.Stderr.WriteString("warning: use of deprecated NewLogger\n")
- return make(Logger)
-}
-
-// Create a new logger with a "stdout" filter configured to send log messages at
-// or above lvl to standard output.
-//
-// DEPRECATED: use NewDefaultLogger instead.
-func NewConsoleLogger(lvl Level) Logger {
- os.Stderr.WriteString("warning: use of deprecated NewConsoleLogger\n")
- return Logger{
- "stdout": &Filter{lvl, NewConsoleLogWriter()},
- }
-}
-
-// Create a new logger with a "stdout" filter configured to send log messages at
-// or above lvl to standard output.
-func NewDefaultLogger(lvl Level) Logger {
- return Logger{
- "stdout": &Filter{lvl, NewConsoleLogWriter()},
- }
-}
-
-// Closes all log writers in preparation for exiting the program or a
-// reconfiguration of logging. Calling this is not really imperative, unless
-// you want to guarantee that all log messages are written. Close removes
-// all filters (and thus all LogWriters) from the logger.
-func (log Logger) Close() {
- // Close all open loggers
- for name, filt := range log {
- filt.Close()
- delete(log, name)
- }
-}
-
-// Add a new LogWriter to the Logger which will only log messages at lvl or
-// higher. This function should not be called from multiple goroutines.
-// Returns the logger for chaining.
-func (log Logger) AddFilter(name string, lvl Level, writer LogWriter) Logger {
- log[name] = &Filter{lvl, writer}
- return log
-}
-
-/******* Logging *******/
-// Send a formatted log message internally
-func (log Logger) intLogf(lvl Level, format string, args ...interface{}) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Determine caller func
- pc, _, lineno, ok := runtime.Caller(2)
- src := ""
- if ok {
- src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
- }
-
- msg := format
- if len(args) > 0 {
- msg = fmt.Sprintf(format, args...)
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: src,
- Message: msg,
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
-}
-
-// Send a closure log message internally
-func (log Logger) intLogc(lvl Level, closure func() string) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Determine caller func
- pc, _, lineno, ok := runtime.Caller(2)
- src := ""
- if ok {
- src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: src,
- Message: closure(),
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
-}
-
-// Send a log message with manual level, source, and message.
-func (log Logger) Log(lvl Level, source, message string) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: source,
- Message: message,
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
-}
-
-// Logf logs a formatted log message at the given log level, using the caller as
-// its source.
-func (log Logger) Logf(lvl Level, format string, args ...interface{}) {
- log.intLogf(lvl, format, args...)
-}
-
-// Logc logs a string returned by the closure at the given log level, using the caller as
-// its source. If no log message would be written, the closure is never called.
-func (log Logger) Logc(lvl Level, closure func() string) {
- log.intLogc(lvl, closure)
-}
-
-// Finest logs a message at the finest log level.
-// See Debug for an explanation of the arguments.
-func (log Logger) Finest(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINEST
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Fine logs a message at the fine log level.
-// See Debug for an explanation of the arguments.
-func (log Logger) Fine(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Debug is a utility method for debug log messages.
-// The behavior of Debug depends on the first argument:
-// - arg0 is a string
-// When given a string as the first argument, this behaves like Logf but with
-// the DEBUG log level: the first argument is interpreted as a format for the
-// latter arguments.
-// - arg0 is a func()string
-// When given a closure of type func()string, this logs the string returned by
-// the closure iff it will be logged. The closure runs at most one time.
-// - arg0 is interface{}
-// When given anything else, the log message will be each of the arguments
-// formatted with %v and separated by spaces (ala Sprint).
-func (log Logger) Debug(arg0 interface{}, args ...interface{}) {
- const (
- lvl = DEBUG
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Trace logs a message at the trace log level.
-// See Debug for an explanation of the arguments.
-func (log Logger) Trace(arg0 interface{}, args ...interface{}) {
- const (
- lvl = TRACE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Info logs a message at the info log level.
-// See Debug for an explanation of the arguments.
-func (log Logger) Info(arg0 interface{}, args ...interface{}) {
- const (
- lvl = INFO
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Warn logs a message at the warning log level and returns the formatted error.
-// At the warning level and higher, there is no performance benefit if the
-// message is not actually logged, because all formats are processed and all
-// closures are executed to format the error message.
-// See Debug for further explanation of the arguments.
-func (log Logger) Warn(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = WARNING
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
-}
-
-// Error logs a message at the error log level and returns the formatted error,
-// See Warn for an explanation of the performance and Debug for an explanation
-// of the parameters.
-func (log Logger) Error(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = ERROR
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
-}
-
-// Critical logs a message at the critical log level and returns the formatted error,
-// See Warn for an explanation of the performance and Debug for an explanation
-// of the parameters.
-func (log Logger) Critical(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = CRITICAL
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go
deleted file mode 100644
index 82b4e36b1..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "bytes"
- "fmt"
- "io"
- "strings"
-)
-
-const (
- FORMAT_DEFAULT = "[%D %T] [%L] (%S) %M"
- FORMAT_SHORT = "[%t %d] [%L] %M"
- FORMAT_ABBREV = "[%L] %M"
-)
-
-type formatCacheType struct {
- LastUpdateSeconds int64
- shortTime, shortDate string
- longTime, longDate string
-}
-
-var formatCache = &formatCacheType{}
-
-// Known format codes:
-// %T - Time (15:04:05 MST)
-// %t - Time (15:04)
-// %D - Date (2006/01/02)
-// %d - Date (01/02/06)
-// %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
-// %S - Source
-// %M - Message
-// Ignores unknown formats
-// Recommended: "[%D %T] [%L] (%S) %M"
-func FormatLogRecord(format string, rec *LogRecord) string {
- if rec == nil {
- return "<nil>"
- }
- if len(format) == 0 {
- return ""
- }
-
- out := bytes.NewBuffer(make([]byte, 0, 64))
- secs := rec.Created.UnixNano() / 1e9
-
- cache := *formatCache
- if cache.LastUpdateSeconds != secs {
- month, day, year := rec.Created.Month(), rec.Created.Day(), rec.Created.Year()
- hour, minute, second := rec.Created.Hour(), rec.Created.Minute(), rec.Created.Second()
- zone, _ := rec.Created.Zone()
- updated := &formatCacheType{
- LastUpdateSeconds: secs,
- shortTime: fmt.Sprintf("%02d:%02d", hour, minute),
- shortDate: fmt.Sprintf("%02d/%02d/%02d", day, month, year%100),
- longTime: fmt.Sprintf("%02d:%02d:%02d %s", hour, minute, second, zone),
- longDate: fmt.Sprintf("%04d/%02d/%02d", year, month, day),
- }
- cache = *updated
- formatCache = updated
- }
-
- // Split the string into pieces by % signs
- pieces := bytes.Split([]byte(format), []byte{'%'})
-
- // Iterate over the pieces, replacing known formats
- for i, piece := range pieces {
- if i > 0 && len(piece) > 0 {
- switch piece[0] {
- case 'T':
- out.WriteString(cache.longTime)
- case 't':
- out.WriteString(cache.shortTime)
- case 'D':
- out.WriteString(cache.longDate)
- case 'd':
- out.WriteString(cache.shortDate)
- case 'L':
- out.WriteString(levelStrings[rec.Level])
- case 'S':
- out.WriteString(rec.Source)
- case 's':
- slice := strings.Split(rec.Source, "/")
- out.WriteString(slice[len(slice)-1])
- case 'M':
- out.WriteString(rec.Message)
- }
- if len(piece) > 1 {
- out.Write(piece[1:])
- }
- } else if len(piece) > 0 {
- out.Write(piece)
- }
- }
- out.WriteByte('\n')
-
- return out.String()
-}
-
-// This is the standard writer that prints to standard output.
-type FormatLogWriter chan *LogRecord
-
-// This creates a new FormatLogWriter
-func NewFormatLogWriter(out io.Writer, format string) FormatLogWriter {
- records := make(FormatLogWriter, LogBufferLength)
- go records.run(out, format)
- return records
-}
-
-func (w FormatLogWriter) run(out io.Writer, format string) {
- for rec := range w {
- fmt.Fprint(out, FormatLogRecord(format, rec))
- }
-}
-
-// This is the FormatLogWriter's output method. This will block if the output
-// buffer is full.
-func (w FormatLogWriter) LogWrite(rec *LogRecord) {
- w <- rec
-}
-
-// Close stops the logger from sending messages to standard output. Attempts to
-// send log messages to this logger after a Close have undefined behavior.
-func (w FormatLogWriter) Close() {
- close(w)
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go
deleted file mode 100644
index 1d224a99d..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "encoding/json"
- "fmt"
- "net"
- "os"
-)
-
-// This log writer sends output to a socket
-type SocketLogWriter chan *LogRecord
-
-// This is the SocketLogWriter's output method
-func (w SocketLogWriter) LogWrite(rec *LogRecord) {
- w <- rec
-}
-
-func (w SocketLogWriter) Close() {
- close(w)
-}
-
-func NewSocketLogWriter(proto, hostport string) SocketLogWriter {
- sock, err := net.Dial(proto, hostport)
- if err != nil {
- fmt.Fprintf(os.Stderr, "NewSocketLogWriter(%q): %s\n", hostport, err)
- return nil
- }
-
- w := SocketLogWriter(make(chan *LogRecord, LogBufferLength))
-
- go func() {
- defer func() {
- if sock != nil && proto == "tcp" {
- sock.Close()
- }
- }()
-
- for rec := range w {
- // Marshall into JSON
- js, err := json.Marshal(rec)
- if err != nil {
- fmt.Fprint(os.Stderr, "SocketLogWriter(%q): %s", hostport, err)
- return
- }
-
- _, err = sock.Write(js)
- if err != nil {
- fmt.Fprint(os.Stderr, "SocketLogWriter(%q): %s", hostport, err)
- return
- }
- }
- }()
-
- return w
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go
deleted file mode 100644
index 8a941e269..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "fmt"
- "io"
- "os"
- "time"
-)
-
-var stdout io.Writer = os.Stdout
-
-// This is the standard writer that prints to standard output.
-type ConsoleLogWriter struct {
- format string
- w chan *LogRecord
-}
-
-// This creates a new ConsoleLogWriter
-func NewConsoleLogWriter() *ConsoleLogWriter {
- consoleWriter := &ConsoleLogWriter{
- format: "[%T %D] [%L] (%S) %M",
- w: make(chan *LogRecord, LogBufferLength),
- }
- go consoleWriter.run(stdout)
- return consoleWriter
-}
-func (c *ConsoleLogWriter) SetFormat(format string) {
- c.format = format
-}
-func (c *ConsoleLogWriter) run(out io.Writer) {
- for rec := range c.w {
- fmt.Fprint(out, FormatLogRecord(c.format, rec))
- }
-}
-
-// This is the ConsoleLogWriter's output method. This will block if the output
-// buffer is full.
-func (c *ConsoleLogWriter) LogWrite(rec *LogRecord) {
- c.w <- rec
-}
-
-// Close stops the logger from sending messages to standard output. Attempts to
-// send log messages to this logger after a Close have undefined behavior.
-func (c *ConsoleLogWriter) Close() {
- close(c.w)
- time.Sleep(50 * time.Millisecond) // Try to give console I/O time to complete
-}
diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go
deleted file mode 100644
index 2ae222b0c..000000000
--- a/Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>. All rights reserved.
-
-package log4go
-
-import (
- "errors"
- "fmt"
- "os"
- "strings"
-)
-
-var (
- Global Logger
-)
-
-func init() {
- Global = NewDefaultLogger(DEBUG)
-}
-
-// Wrapper for (*Logger).LoadConfiguration
-func LoadConfiguration(filename string) {
- Global.LoadConfiguration(filename)
-}
-
-// Wrapper for (*Logger).AddFilter
-func AddFilter(name string, lvl Level, writer LogWriter) {
- Global.AddFilter(name, lvl, writer)
-}
-
-// Wrapper for (*Logger).Close (closes and removes all logwriters)
-func Close() {
- Global.Close()
-}
-
-func Crash(args ...interface{}) {
- if len(args) > 0 {
- Global.intLogf(CRITICAL, strings.Repeat(" %v", len(args))[1:], args...)
- }
- panic(args)
-}
-
-// Logs the given message and crashes the program
-func Crashf(format string, args ...interface{}) {
- Global.intLogf(CRITICAL, format, args...)
- Global.Close() // so that hopefully the messages get logged
- panic(fmt.Sprintf(format, args...))
-}
-
-// Compatibility with `log`
-func Exit(args ...interface{}) {
- if len(args) > 0 {
- Global.intLogf(ERROR, strings.Repeat(" %v", len(args))[1:], args...)
- }
- Global.Close() // so that hopefully the messages get logged
- os.Exit(0)
-}
-
-// Compatibility with `log`
-func Exitf(format string, args ...interface{}) {
- Global.intLogf(ERROR, format, args...)
- Global.Close() // so that hopefully the messages get logged
- os.Exit(0)
-}
-
-// Compatibility with `log`
-func Stderr(args ...interface{}) {
- if len(args) > 0 {
- Global.intLogf(ERROR, strings.Repeat(" %v", len(args))[1:], args...)
- }
-}
-
-// Compatibility with `log`
-func Stderrf(format string, args ...interface{}) {
- Global.intLogf(ERROR, format, args...)
-}
-
-// Compatibility with `log`
-func Stdout(args ...interface{}) {
- if len(args) > 0 {
- Global.intLogf(INFO, strings.Repeat(" %v", len(args))[1:], args...)
- }
-}
-
-// Compatibility with `log`
-func Stdoutf(format string, args ...interface{}) {
- Global.intLogf(INFO, format, args...)
-}
-
-// Send a log message manually
-// Wrapper for (*Logger).Log
-func Log(lvl Level, source, message string) {
- Global.Log(lvl, source, message)
-}
-
-// Send a formatted log message easily
-// Wrapper for (*Logger).Logf
-func Logf(lvl Level, format string, args ...interface{}) {
- Global.intLogf(lvl, format, args...)
-}
-
-// Send a closure log message
-// Wrapper for (*Logger).Logc
-func Logc(lvl Level, closure func() string) {
- Global.intLogc(lvl, closure)
-}
-
-// Utility for finest log messages (see Debug() for parameter explanation)
-// Wrapper for (*Logger).Finest
-func Finest(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINEST
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- Global.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Utility for fine log messages (see Debug() for parameter explanation)
-// Wrapper for (*Logger).Fine
-func Fine(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- Global.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Utility for debug log messages
-// When given a string as the first argument, this behaves like Logf but with the DEBUG log level (e.g. the first argument is interpreted as a format for the latter arguments)
-// When given a closure of type func()string, this logs the string returned by the closure iff it will be logged. The closure runs at most one time.
-// When given anything else, the log message will be each of the arguments formatted with %v and separated by spaces (ala Sprint).
-// Wrapper for (*Logger).Debug
-func Debug(arg0 interface{}, args ...interface{}) {
- const (
- lvl = DEBUG
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- Global.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Utility for trace log messages (see Debug() for parameter explanation)
-// Wrapper for (*Logger).Trace
-func Trace(arg0 interface{}, args ...interface{}) {
- const (
- lvl = TRACE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- Global.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Utility for info log messages (see Debug() for parameter explanation)
-// Wrapper for (*Logger).Info
-func Info(arg0 interface{}, args ...interface{}) {
- const (
- lvl = INFO
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- Global.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
-}
-
-// Utility for warn log messages (returns an error for easy function returns) (see Debug() for parameter explanation)
-// These functions will execute a closure exactly once, to build the error message for the return
-// Wrapper for (*Logger).Warn
-func Warn(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = WARNING
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- return errors.New(fmt.Sprintf(first, args...))
- case func() string:
- // Log the closure (no other arguments used)
- str := first()
- Global.intLogf(lvl, "%s", str)
- return errors.New(str)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...))
- }
- return nil
-}
-
-// Utility for error log messages (returns an error for easy function returns) (see Debug() for parameter explanation)
-// These functions will execute a closure exactly once, to build the error message for the return
-// Wrapper for (*Logger).Error
-func Error(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = ERROR
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- return errors.New(fmt.Sprintf(first, args...))
- case func() string:
- // Log the closure (no other arguments used)
- str := first()
- Global.intLogf(lvl, "%s", str)
- return errors.New(str)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...))
- }
- return nil
-}
-
-// Utility for critical log messages (returns an error for easy function returns) (see Debug() for parameter explanation)
-// These functions will execute a closure exactly once, to build the error message for the return
-// Wrapper for (*Logger).Critical
-func Critical(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = CRITICAL
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- Global.intLogf(lvl, first, args...)
- return errors.New(fmt.Sprintf(first, args...))
- case func() string:
- // Log the closure (no other arguments used)
- str := first()
- Global.intLogf(lvl, "%s", str)
- return errors.New(str)
- default:
- // Build a format string so that it will be similar to Sprint
- Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...))
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/LICENSE b/Godeps/_workspace/src/github.com/braintree/manners/LICENSE
deleted file mode 100644
index 91ef5beed..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2014 Braintree, a division of PayPal, Inc.
-
-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.
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/README.md b/Godeps/_workspace/src/github.com/braintree/manners/README.md
deleted file mode 100644
index 09f6f9693..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Manners
-
-A *polite* webserver for Go.
-
-Manners allows you to shut your Go webserver down gracefully, without dropping any requests. It can act as a drop-in replacement for the standard library's http.ListenAndServe function:
-
-```go
-func main() {
- handler := MyHTTPHandler()
- manners.ListenAndServe(":7000", handler)
-}
-```
-
-Then, when you want to shut the server down:
-
-```go
-manners.Close()
-```
-
-(Note that this does not block until all the requests are finished. Rather, the call to manners.ListenAndServe will stop blocking when all the requests are finished.)
-
-Manners ensures that all requests are served by incrementing a WaitGroup when a request comes in and decrementing it when the request finishes.
-
-If your request handler spawns Goroutines that are not guaranteed to finish with the request, you can ensure they are also completed with the `StartRoutine` and `FinishRoutine` functions on the server.
-
-### Known Issues
-
-Manners does not correctly shut down long-lived keepalive connections when issued a shutdown command. Clients on an idle keepalive connection may see a connection reset error rather than a close. See https://github.com/braintree/manners/issues/13 for details.
-
-### Compatability
-
-Manners 0.3.0 and above uses standard library functionality introduced in Go 1.3.
-
-### Installation
-
-`go get github.com/braintree/manners`
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/interfaces.go b/Godeps/_workspace/src/github.com/braintree/manners/interfaces.go
deleted file mode 100644
index fd0732857..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/interfaces.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package manners
-
-type waitGroup interface {
- Add(int)
- Done()
- Wait()
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/server.go b/Godeps/_workspace/src/github.com/braintree/manners/server.go
deleted file mode 100644
index e45f5c64b..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/server.go
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
-Package manners provides a wrapper for a standard net/http server that
-ensures all active HTTP client have completed their current request
-before the server shuts down.
-
-It can be used a drop-in replacement for the standard http package,
-or can wrap a pre-configured Server.
-
-eg.
-
- http.Handle("/hello", func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("Hello\n"))
- })
-
- log.Fatal(manners.ListenAndServe(":8080", nil))
-
-or for a customized server:
-
- s := manners.NewWithServer(&http.Server{
- Addr: ":8080",
- Handler: myHandler,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- })
- log.Fatal(s.ListenAndServe())
-
-The server will shut down cleanly when the Close() method is called:
-
- go func() {
- sigchan := make(chan os.Signal, 1)
- signal.Notify(sigchan, os.Interrupt, os.Kill)
- <-sigchan
- log.Info("Shutting down...")
- manners.Close()
- }()
-
- http.Handle("/hello", myHandler)
- log.Fatal(manners.ListenAndServe(":8080", nil))
-*/
-package manners
-
-import (
- "crypto/tls"
- "net"
- "net/http"
- "sync"
- "sync/atomic"
-)
-
-// A GracefulServer maintains a WaitGroup that counts how many in-flight
-// requests the server is handling. When it receives a shutdown signal,
-// it stops accepting new requests but does not actually shut down until
-// all in-flight requests terminate.
-//
-// GracefulServer embeds the underlying net/http.Server making its non-override
-// methods and properties avaiable.
-//
-// It must be initialized by calling NewWithServer.
-type GracefulServer struct {
- *http.Server
-
- shutdown chan bool
- shutdownFinished chan bool
- wg waitGroup
-
- lcsmu sync.RWMutex
- connections map[net.Conn]bool
-
- up chan net.Listener // Only used by test code.
-}
-
-// NewWithServer wraps an existing http.Server object and returns a
-// GracefulServer that supports all of the original Server operations.
-func NewWithServer(s *http.Server) *GracefulServer {
- return &GracefulServer{
- Server: s,
- shutdown: make(chan bool),
- shutdownFinished: make(chan bool, 1),
- wg: new(sync.WaitGroup),
- connections: make(map[net.Conn]bool),
- }
-}
-
-// Close stops the server from accepting new requets and begins shutting down.
-// It returns true if it's the first time Close is called.
-func (s *GracefulServer) Close() bool {
- return <-s.shutdown
-}
-
-// BlockingClose is similar to Close, except that it blocks until the last
-// connection has been closed.
-func (s *GracefulServer) BlockingClose() bool {
- result := s.Close()
- <-s.shutdownFinished
- return result
-}
-
-// ListenAndServe provides a graceful equivalent of net/http.Serve.ListenAndServe.
-func (s *GracefulServer) ListenAndServe() error {
- addr := s.Addr
- if addr == "" {
- addr = ":http"
- }
- listener, err := net.Listen("tcp", addr)
- if err != nil {
- return err
- }
-
- return s.Serve(listener)
-}
-
-// ListenAndServeTLS provides a graceful equivalent of net/http.Serve.ListenAndServeTLS.
-func (s *GracefulServer) ListenAndServeTLS(certFile, keyFile string) error {
- // direct lift from net/http/server.go
- addr := s.Addr
- if addr == "" {
- addr = ":https"
- }
- config := &tls.Config{}
- if s.TLSConfig != nil {
- *config = *s.TLSConfig
- }
- if config.NextProtos == nil {
- config.NextProtos = []string{"http/1.1"}
- }
-
- var err error
- config.Certificates = make([]tls.Certificate, 1)
- config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
- return err
- }
-
- ln, err := net.Listen("tcp", addr)
- if err != nil {
- return err
- }
-
- return s.Serve(tls.NewListener(ln, config))
-}
-
-// Serve provides a graceful equivalent net/http.Server.Serve.
-func (s *GracefulServer) Serve(listener net.Listener) error {
- // Wrap the server HTTP handler into graceful one, that will close kept
- // alive connections if a new request is received after shutdown.
- gracefulHandler := newGracefulHandler(s.Server.Handler)
- s.Server.Handler = gracefulHandler
-
- // Start a goroutine that waits for a shutdown signal and will stop the
- // listener when it receives the signal. That in turn will result in
- // unblocking of the http.Serve call.
- go func() {
- s.shutdown <- true
- close(s.shutdown)
- gracefulHandler.Close()
- s.Server.SetKeepAlivesEnabled(false)
- listener.Close()
- }()
-
- originalConnState := s.Server.ConnState
-
- // s.ConnState is invoked by the net/http.Server every time a connection
- // changes state. It keeps track of each connection's state over time,
- // enabling manners to handle persisted connections correctly.
- s.ConnState = func(conn net.Conn, newState http.ConnState) {
- s.lcsmu.RLock()
- protected := s.connections[conn]
- s.lcsmu.RUnlock()
-
- switch newState {
-
- case http.StateNew:
- // New connection -> StateNew
- protected = true
- s.StartRoutine()
-
- case http.StateActive:
- // (StateNew, StateIdle) -> StateActive
- if gracefulHandler.IsClosed() {
- conn.Close()
- break
- }
-
- if !protected {
- protected = true
- s.StartRoutine()
- }
-
- default:
- // (StateNew, StateActive) -> (StateIdle, StateClosed, StateHiJacked)
- if protected {
- s.FinishRoutine()
- protected = false
- }
- }
-
- s.lcsmu.Lock()
- if newState == http.StateClosed || newState == http.StateHijacked {
- delete(s.connections, conn)
- } else {
- s.connections[conn] = protected
- }
- s.lcsmu.Unlock()
-
- if originalConnState != nil {
- originalConnState(conn, newState)
- }
- }
-
- // A hook to allow the server to notify others when it is ready to receive
- // requests; only used by tests.
- if s.up != nil {
- s.up <- listener
- }
-
- err := s.Server.Serve(listener)
- // An error returned on shutdown is not worth reporting.
- if err != nil && gracefulHandler.IsClosed() {
- err = nil
- }
-
- // Wait for pending requests to complete regardless the Serve result.
- s.wg.Wait()
- s.shutdownFinished <- true
- return err
-}
-
-// StartRoutine increments the server's WaitGroup. Use this if a web request
-// starts more goroutines and these goroutines are not guaranteed to finish
-// before the request.
-func (s *GracefulServer) StartRoutine() {
- s.wg.Add(1)
-}
-
-// FinishRoutine decrements the server's WaitGroup. Use this to complement
-// StartRoutine().
-func (s *GracefulServer) FinishRoutine() {
- s.wg.Done()
-}
-
-// gracefulHandler is used by GracefulServer to prevent calling ServeHTTP on
-// to be closed kept-alive connections during the server shutdown.
-type gracefulHandler struct {
- closed int32 // accessed atomically.
- wrapped http.Handler
-}
-
-func newGracefulHandler(wrapped http.Handler) *gracefulHandler {
- return &gracefulHandler{
- wrapped: wrapped,
- }
-}
-
-func (gh *gracefulHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if atomic.LoadInt32(&gh.closed) == 0 {
- gh.wrapped.ServeHTTP(w, r)
- return
- }
- r.Body.Close()
- // Server is shutting down at this moment, and the connection that this
- // handler is being called on is about to be closed. So we do not need to
- // actually execute the handler logic.
-}
-
-func (gh *gracefulHandler) Close() {
- atomic.StoreInt32(&gh.closed, 1)
-}
-
-func (gh *gracefulHandler) IsClosed() bool {
- return atomic.LoadInt32(&gh.closed) == 1
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/static.go b/Godeps/_workspace/src/github.com/braintree/manners/static.go
deleted file mode 100644
index 2a74b094b..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/static.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package manners
-
-import (
- "net"
- "net/http"
-)
-
-var defaultServer *GracefulServer
-
-// ListenAndServe provides a graceful version of the function provided by the
-// net/http package. Call Close() to stop the server.
-func ListenAndServe(addr string, handler http.Handler) error {
- defaultServer = NewWithServer(&http.Server{Addr: addr, Handler: handler})
- return defaultServer.ListenAndServe()
-}
-
-// ListenAndServeTLS provides a graceful version of the function provided by the
-// net/http package. Call Close() to stop the server.
-func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error {
- defaultServer = NewWithServer(&http.Server{Addr: addr, Handler: handler})
- return defaultServer.ListenAndServeTLS(certFile, keyFile)
-}
-
-// Serve provides a graceful version of the function provided by the net/http
-// package. Call Close() to stop the server.
-func Serve(l net.Listener, handler http.Handler) error {
- defaultServer = NewWithServer(&http.Server{Handler: handler})
- return defaultServer.Serve(l)
-}
-
-// Shuts down the default server used by ListenAndServe, ListenAndServeTLS and
-// Serve. It returns true if it's the first time Close is called.
-func Close() bool {
- return defaultServer.Close()
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/certs.go b/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/certs.go
deleted file mode 100644
index ede248b3d..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/certs.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package test_helpers
-
-// A PEM-encoded TLS cert with SAN IPs "127.0.0.1" and "[::1]", expiring at the
-// last second of 2049 (the end of ASN.1 time).
-
-// generated from src/pkg/crypto/tls:
-// go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
-var (
- Cert = []byte(`-----BEGIN CERTIFICATE-----
-MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
-bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
-bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
-IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
-AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
-EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
-AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
-Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
------END CERTIFICATE-----`)
-
- Key = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
-0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
-NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
-AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
-MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
-EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
-1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
------END RSA PRIVATE KEY-----`)
-)
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/conn.go b/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/conn.go
deleted file mode 100644
index 8c610f58e..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/conn.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package test_helpers
-
-import "net"
-
-type Conn struct {
- net.Conn
- CloseCalled bool
-}
-
-func (c *Conn) Close() error {
- c.CloseCalled = true
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/listener.go b/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/listener.go
deleted file mode 100644
index e3af35a6e..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/listener.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package test_helpers
-
-import (
- "errors"
- "net"
-)
-
-type Listener struct {
- AcceptRelease chan bool
- CloseCalled chan bool
-}
-
-func NewListener() *Listener {
- return &Listener{
- make(chan bool, 1),
- make(chan bool, 1),
- }
-}
-
-func (l *Listener) Addr() net.Addr {
- addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
- return addr
-}
-
-func (l *Listener) Close() error {
- l.CloseCalled <- true
- l.AcceptRelease <- true
- return nil
-}
-
-func (l *Listener) Accept() (net.Conn, error) {
- <-l.AcceptRelease
- return nil, errors.New("connection closed")
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/temp_file.go b/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/temp_file.go
deleted file mode 100644
index c4aa263a0..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/temp_file.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package test_helpers
-
-import (
- "io/ioutil"
- "os"
-)
-
-type TempFile struct {
- *os.File
-}
-
-func NewTempFile(content []byte) (*TempFile, error) {
- f, err := ioutil.TempFile("", "graceful-test")
- if err != nil {
- return nil, err
- }
-
- f.Write(content)
- return &TempFile{f}, nil
-}
-
-func (tf *TempFile) Unlink() {
- if tf.File != nil {
- os.Remove(tf.Name())
- tf.File = nil
- }
-}
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/wait_group.go b/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/wait_group.go
deleted file mode 100644
index 1df590db7..000000000
--- a/Godeps/_workspace/src/github.com/braintree/manners/test_helpers/wait_group.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package test_helpers
-
-import "sync"
-
-type WaitGroup struct {
- sync.Mutex
- Count int
- WaitCalled chan int
-}
-
-func NewWaitGroup() *WaitGroup {
- return &WaitGroup{
- WaitCalled: make(chan int, 1),
- }
-}
-
-func (wg *WaitGroup) Add(delta int) {
- wg.Lock()
- wg.Count++
- wg.Unlock()
-}
-
-func (wg *WaitGroup) Done() {
- wg.Lock()
- wg.Count--
- wg.Unlock()
-}
-
-func (wg *WaitGroup) Wait() {
- wg.Lock()
- wg.WaitCalled <- wg.Count
- wg.Unlock()
-}
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/.travis.yml b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/.travis.yml
deleted file mode 100644
index b19c2e535..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: go
-go:
- - 1.2
-before_install:
-- go get github.com/onsi/ginkgo/...
-- go get github.com/onsi/gomega/...
-- go install github.com/onsi/ginkgo/ginkgo
-script: PATH=$PATH:$HOME/gopath/bin ginkgo -r .
-branches:
- only:
- - master
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/LICENSE b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/LICENSE
deleted file mode 100644
index 915b20892..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright 2014 Pivotal
-
-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.
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/README.md b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/README.md
deleted file mode 100644
index d696eb6b6..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Jibber Jabber [![Build Status](https://travis-ci.org/cloudfoundry/jibber_jabber.svg?branch=master)](https://travis-ci.org/cloudfoundry/jibber_jabber)
-Jibber Jabber is a GoLang Library that can be used to detect an operating system's current language.
-
-### OS Support
-
-OSX and Linux via the `LC_ALL` and `LANG` environment variables. These are standard variables that are used in ALL versions of UNIX for language detection.
-
-Windows via [GetUserDefaultLocaleName](http://msdn.microsoft.com/en-us/library/windows/desktop/dd318136.aspx) and [GetSystemDefaultLocaleName](http://msdn.microsoft.com/en-us/library/windows/desktop/dd318122.aspx) system calls. These calls are supported in Windows Vista and up.
-
-# Usage
-Add the following line to your go `import`:
-
-```
- "github.com/cloudfoundry/jibber_jabber"
-```
-
-### DetectIETF
-`DetectIETF` will return the current locale as a string. The format of the locale will be the [ISO 639](http://en.wikipedia.org/wiki/ISO_639) two-letter language code, a DASH, then an [ISO 3166](http://en.wikipedia.org/wiki/ISO_3166-1) two-letter country code.
-
-```
- userLocale, err := jibber_jabber.DetectIETF()
- println("Locale:", userLocale)
-```
-
-### DetectLanguage
-`DetectLanguage` will return the current languge as a string. The format will be the [ISO 639](http://en.wikipedia.org/wiki/ISO_639) two-letter language code.
-
-```
- userLanguage, err := jibber_jabber.DetectLanguage()
- println("Language:", userLanguage)
-```
-
-### DetectTerritory
-`DetectTerritory` will return the current locale territory as a string. The format will be the [ISO 3166](http://en.wikipedia.org/wiki/ISO_3166-1) two-letter country code.
-
-```
- localeTerritory, err := jibber_jabber.DetectTerritory()
- println("Territory:", localeTerritory)
-```
-
-### Errors
-All the Detect commands will return an error if they are unable to read the Locale from the system.
-
-For Windows, additional error information is provided due to the nature of the system call being used.
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/ci/scripts/windows-64-test.bat b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/ci/scripts/windows-64-test.bat
deleted file mode 100644
index b9a87bf7a..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/ci/scripts/windows-64-test.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-git fetch
-git checkout %GIT_COMMIT%
-
-SET GOPATH=%CD%\Godeps\_workspace;c:\Users\Administrator\go
-c:\Go\bin\go test -v .
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber.go b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber.go
deleted file mode 100644
index 45d288ea8..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package jibber_jabber
-
-import (
- "strings"
-)
-
-const (
- COULD_NOT_DETECT_PACKAGE_ERROR_MESSAGE = "Could not detect Language"
-)
-
-func splitLocale(locale string) (string, string) {
- formattedLocale := strings.Split(locale, ".")[0]
- formattedLocale = strings.Replace(formattedLocale, "-", "_", -1)
-
- pieces := strings.Split(formattedLocale, "_")
- language := pieces[0]
- territory := ""
- if len(pieces) > 1 {
- territory = strings.Split(formattedLocale, "_")[1]
- }
- return language, territory
-}
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_unix.go b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_unix.go
deleted file mode 100644
index 374d76176..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_unix.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// +build darwin freebsd linux netbsd openbsd
-
-package jibber_jabber
-
-import (
- "errors"
- "os"
- "strings"
-)
-
-func getLangFromEnv() (locale string) {
- locale = os.Getenv("LC_ALL")
- if locale == "" {
- locale = os.Getenv("LANG")
- }
- return
-}
-
-func getUnixLocale() (unix_locale string, err error) {
- unix_locale = getLangFromEnv()
- if unix_locale == "" {
- err = errors.New(COULD_NOT_DETECT_PACKAGE_ERROR_MESSAGE)
- }
-
- return
-}
-
-func DetectIETF() (locale string, err error) {
- unix_locale, err := getUnixLocale()
- if err == nil {
- language, territory := splitLocale(unix_locale)
- locale = language
- if territory != "" {
- locale = strings.Join([]string{language, territory}, "-")
- }
- }
-
- return
-}
-
-func DetectLanguage() (language string, err error) {
- unix_locale, err := getUnixLocale()
- if err == nil {
- language, _ = splitLocale(unix_locale)
- }
-
- return
-}
-
-func DetectTerritory() (territory string, err error) {
- unix_locale, err := getUnixLocale()
- if err == nil {
- _, territory = splitLocale(unix_locale)
- }
-
- return
-}
diff --git a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_windows.go b/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_windows.go
deleted file mode 100644
index 1acd96c38..000000000
--- a/Godeps/_workspace/src/github.com/cloudfoundry/jibber_jabber/jibber_jabber_windows.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// +build windows
-
-package jibber_jabber
-
-import (
- "errors"
- "syscall"
- "unsafe"
-)
-
-const LOCALE_NAME_MAX_LENGTH uint32 = 85
-
-var SUPPORTED_LOCALES = map[uintptr]string{
- 0x0407: "de-DE",
- 0x0409: "en-US",
- 0x0c0a: "es-ES", //or is it 0x040a
- 0x040c: "fr-FR",
- 0x0410: "it-IT",
- 0x0411: "ja-JA",
- 0x0412: "ko_KR",
- 0x0416: "pt-BR",
- //0x0419: "ru_RU", - Will add support for Russian when nicksnyder/go-i18n supports Russian
- 0x0804: "zh-CN",
- 0x0c04: "zh-HK",
- 0x0404: "zh-TW",
-}
-
-func getWindowsLocaleFrom(sysCall string) (locale string, err error) {
- buffer := make([]uint16, LOCALE_NAME_MAX_LENGTH)
-
- dll := syscall.MustLoadDLL("kernel32")
- proc := dll.MustFindProc(sysCall)
- r, _, dllError := proc.Call(uintptr(unsafe.Pointer(&buffer[0])), uintptr(LOCALE_NAME_MAX_LENGTH))
- if r == 0 {
- err = errors.New(COULD_NOT_DETECT_PACKAGE_ERROR_MESSAGE + ":\n" + dllError.Error())
- return
- }
-
- locale = syscall.UTF16ToString(buffer)
-
- return
-}
-
-func getAllWindowsLocaleFrom(sysCall string) (string, error) {
- dll, err := syscall.LoadDLL("kernel32")
- if err != nil {
- return "", errors.New("Could not find kernel32 dll")
- }
-
- proc, err := dll.FindProc(sysCall)
- if err != nil {
- return "", err
- }
-
- locale, _, dllError := proc.Call()
- if locale == 0 {
- return "", errors.New(COULD_NOT_DETECT_PACKAGE_ERROR_MESSAGE + ":\n" + dllError.Error())
- }
-
- return SUPPORTED_LOCALES[locale], nil
-}
-
-func getWindowsLocale() (locale string, err error) {
- dll, err := syscall.LoadDLL("kernel32")
- if err != nil {
- return "", errors.New("Could not find kernel32 dll")
- }
-
- proc, err := dll.FindProc("GetVersion")
- if err != nil {
- return "", err
- }
-
- v, _, _ := proc.Call()
- windowsVersion := byte(v)
- isVistaOrGreater := (windowsVersion >= 6)
-
- if isVistaOrGreater {
- locale, err = getWindowsLocaleFrom("GetUserDefaultLocaleName")
- if err != nil {
- locale, err = getWindowsLocaleFrom("GetSystemDefaultLocaleName")
- }
- } else if !isVistaOrGreater {
- locale, err = getAllWindowsLocaleFrom("GetUserDefaultLCID")
- if err != nil {
- locale, err = getAllWindowsLocaleFrom("GetSystemDefaultLCID")
- }
- } else {
- panic(v)
- }
- return
-}
-func DetectIETF() (locale string, err error) {
- locale, err = getWindowsLocale()
- return
-}
-
-func DetectLanguage() (language string, err error) {
- windows_locale, err := getWindowsLocale()
- if err == nil {
- language, _ = splitLocale(windows_locale)
- }
-
- return
-}
-
-func DetectTerritory() (territory string, err error) {
- windows_locale, err := getWindowsLocale()
- if err == nil {
- _, territory = splitLocale(windows_locale)
- }
-
- return
-}
diff --git a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/.travis.yml b/Godeps/_workspace/src/github.com/dgryski/dgoogauth/.travis.yml
deleted file mode 100644
index 4f2ee4d97..000000000
--- a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: go
diff --git a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/README.md b/Godeps/_workspace/src/github.com/dgryski/dgoogauth/README.md
deleted file mode 100644
index 75fdde78a..000000000
--- a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a Go implementation of the Google Authenticator library.
-
-[![Build Status](https://travis-ci.org/dgryski/dgoogauth.png)](https://travis-ci.org/dgryski/dgoogauth)
-
-Copyright (c) 2012 Damian Gryski <damian@gryski.com>
-This code is licensed under the Apache License, version 2.0
-
-It implements the one-time-password algorithms specified in:
-
-* RFC 4226 (HOTP: An HMAC-Based One-Time Password Algorithm)
-* RFC 6238 (TOTP: Time-Based One-Time Password Algorithm)
-
-You can learn more about the Google Authenticator library at its project page:
-
-* https://github.com/google/google-authenticator
diff --git a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth.go b/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth.go
deleted file mode 100644
index 1efddcc20..000000000
--- a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth.go
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-Package dgoogauth implements the one-time password algorithms supported by Google Authenticator
-
-This package supports the HMAC-Based One-time Password (HOTP) algorithm
-specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm
-specified in RFC 6238.
-*/
-package dgoogauth
-
-import (
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base32"
- "encoding/binary"
- "errors"
- "net/url"
- "sort"
- "strconv"
- "time"
-)
-
-// Much of this code assumes int == int64, which probably is not the case.
-
-// ComputeCode computes the response code for a 64-bit challenge 'value' using the secret 'secret'.
-// To avoid breaking compatibility with the previous API, it returns an invalid code (-1) when an error occurs,
-// but does not silently ignore them (it forces a mismatch so the code will be rejected).
-func ComputeCode(secret string, value int64) int {
-
- key, err := base32.StdEncoding.DecodeString(secret)
- if err != nil {
- return -1
- }
-
- hash := hmac.New(sha1.New, key)
- err = binary.Write(hash, binary.BigEndian, value)
- if err != nil {
- return -1
- }
- h := hash.Sum(nil)
-
- offset := h[19] & 0x0f
-
- truncated := binary.BigEndian.Uint32(h[offset : offset+4])
-
- truncated &= 0x7fffffff
- code := truncated % 1000000
-
- return int(code)
-}
-
-// ErrInvalidCode indicate the supplied one-time code was not valid
-var ErrInvalidCode = errors.New("invalid code")
-
-// OTPConfig is a one-time-password configuration. This object will be modified by calls to
-// Authenticate and should be saved to ensure the codes are in fact only used
-// once.
-type OTPConfig struct {
- Secret string // 80-bit base32 encoded string of the user's secret
- WindowSize int // valid range: technically 0..100 or so, but beyond 3-5 is probably bad security
- HotpCounter int // the current otp counter. 0 if the user uses time-based codes instead.
- DisallowReuse []int // timestamps in the current window unavailable for re-use
- ScratchCodes []int // an array of 8-digit numeric codes that can be used to log in
- UTC bool // use UTC for the timestamp instead of local time
-}
-
-func (c *OTPConfig) checkScratchCodes(code int) bool {
-
- for i, v := range c.ScratchCodes {
- if code == v {
- // remove this code from the list of valid ones
- l := len(c.ScratchCodes) - 1
- c.ScratchCodes[i] = c.ScratchCodes[l] // copy last element over this element
- c.ScratchCodes = c.ScratchCodes[0:l] // and trim the list length by 1
- return true
- }
- }
-
- return false
-}
-
-func (c *OTPConfig) checkHotpCode(code int) bool {
-
- for i := 0; i < c.WindowSize; i++ {
- if ComputeCode(c.Secret, int64(c.HotpCounter+i)) == code {
- c.HotpCounter += i + 1
- // We don't check for overflow here, which means you can only authenticate 2^63 times
- // After that, the counter is negative and the above 'if' test will fail.
- // This matches the behaviour of the PAM module.
- return true
- }
- }
-
- // we must always advance the counter if we tried to authenticate with it
- c.HotpCounter++
- return false
-}
-
-func (c *OTPConfig) checkTotpCode(t0, code int) bool {
-
- minT := t0 - (c.WindowSize / 2)
- maxT := t0 + (c.WindowSize / 2)
- for t := minT; t <= maxT; t++ {
- if ComputeCode(c.Secret, int64(t)) == code {
-
- if c.DisallowReuse != nil {
- for _, timeCode := range c.DisallowReuse {
- if timeCode == t {
- return false
- }
- }
-
- // code hasn't been used before
- c.DisallowReuse = append(c.DisallowReuse, t)
-
- // remove all time codes outside of the valid window
- sort.Ints(c.DisallowReuse)
- min := 0
- for c.DisallowReuse[min] < minT {
- min++
- }
- // FIXME: check we don't have an off-by-one error here
- c.DisallowReuse = c.DisallowReuse[min:]
- }
-
- return true
- }
- }
-
- return false
-}
-
-// Authenticate a one-time-password against the given OTPConfig
-// Returns true/false if the authentication was successful.
-// Returns error if the password is incorrectly formatted (not a zero-padded 6 or non-zero-padded 8 digit number).
-func (c *OTPConfig) Authenticate(password string) (bool, error) {
-
- var scratch bool
-
- switch {
- case len(password) == 6 && password[0] >= '0' && password[0] <= '9':
- break
- case len(password) == 8 && password[0] >= '1' && password[0] <= '9':
- scratch = true
- break
- default:
- return false, ErrInvalidCode
- }
-
- code, err := strconv.Atoi(password)
-
- if err != nil {
- return false, ErrInvalidCode
- }
-
- if scratch {
- return c.checkScratchCodes(code), nil
- }
-
- // we have a counter value we can use
- if c.HotpCounter > 0 {
- return c.checkHotpCode(code), nil
- }
-
- var t0 int
- // assume we're on Time-based OTP
- if c.UTC {
- t0 = int(time.Now().UTC().Unix() / 30)
- } else {
- t0 = int(time.Now().Unix() / 30)
- }
- return c.checkTotpCode(t0, code), nil
-}
-
-// ProvisionURI generates a URI that can be turned into a QR code to configure
-// a Google Authenticator mobile app.
-func (c *OTPConfig) ProvisionURI(user string) string {
- return c.ProvisionURIWithIssuer(user, "")
-}
-
-// ProvisionURIWithIssuer generates a URI that can be turned into a QR code
-// to configure a Google Authenticator mobile app. It respects the recommendations
-// on how to avoid conflicting accounts.
-//
-// See https://code.google.com/p/google-authenticator/wiki/ConflictingAccounts
-func (c *OTPConfig) ProvisionURIWithIssuer(user string, issuer string) string {
- auth := "totp/"
- q := make(url.Values)
- if c.HotpCounter > 0 {
- auth = "hotp/"
- q.Add("counter", strconv.Itoa(c.HotpCounter))
- }
- q.Add("secret", c.Secret)
- if issuer != "" {
- q.Add("issuer", issuer)
- auth += issuer + ":"
- }
-
- return "otpauth://" + auth + user + "?" + q.Encode()
-}
diff --git a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth_test.go b/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth_test.go
deleted file mode 100644
index 031922c47..000000000
--- a/Godeps/_workspace/src/github.com/dgryski/dgoogauth/googauth_test.go
+++ /dev/null
@@ -1,251 +0,0 @@
-package dgoogauth
-
-import (
- "strconv"
- "testing"
- "time"
-)
-
-// Test vectors via:
-// http://code.google.com/p/google-authenticator/source/browse/libpam/pam_google_authenticator_unittest.c
-// https://google-authenticator.googlecode.com/hg/libpam/totp.html
-
-var codeTests = []struct {
- secret string
- value int64
- code int
-}{
- {"2SH3V3GDW7ZNMGYE", 1, 293240},
- {"2SH3V3GDW7ZNMGYE", 5, 932068},
- {"2SH3V3GDW7ZNMGYE", 10000, 50548},
-}
-
-func TestCode(t *testing.T) {
-
- for _, v := range codeTests {
- c := ComputeCode(v.secret, v.value)
-
- if c != v.code {
- t.Errorf("computeCode(%s, %d): got %d expected %d\n", v.secret, v.value, c, v.code)
- }
-
- }
-}
-
-func TestScratchCode(t *testing.T) {
-
- var cotp OTPConfig
-
- cotp.ScratchCodes = []int{11112222, 22223333}
-
- var scratchTests = []struct {
- code int
- result bool
- }{
- {33334444, false},
- {11112222, true},
- {11112222, false},
- {22223333, true},
- {22223333, false},
- {33334444, false},
- }
-
- for _, s := range scratchTests {
- r := cotp.checkScratchCodes(s.code)
- if r != s.result {
- t.Errorf("scratchcode(%d) failed: got %t expected %t", s.code, r, s.result)
- }
- }
-}
-
-func TestHotpCode(t *testing.T) {
-
- var cotp OTPConfig
-
- // reuse our test values from above
- // perhaps create more?
- cotp.Secret = "2SH3V3GDW7ZNMGYE"
- cotp.HotpCounter = 1
- cotp.WindowSize = 3
-
- var counterCodes = []struct {
- code int
- result bool
- counter int
- }{
- { /* 1 */ 293240, true, 2}, // increments on success
- { /* 1 */ 293240, false, 3}, // and failure
- { /* 5 */ 932068, true, 6}, // inside of window
- { /* 10 */ 481725, false, 7}, // outside of window
- { /* 10 */ 481725, false, 8}, // outside of window
- { /* 10 */ 481725, true, 11}, // now inside of window
- }
-
- for i, s := range counterCodes {
- r := cotp.checkHotpCode(s.code)
- if r != s.result {
- t.Errorf("counterCode(%d) (step %d) failed: got %t expected %t", s.code, i, r, s.result)
- }
- if cotp.HotpCounter != s.counter {
- t.Errorf("hotpCounter incremented poorly: got %d expected %d", cotp.HotpCounter, s.counter)
- }
- }
-}
-
-func TestTotpCode(t *testing.T) {
-
- var cotp OTPConfig
-
- // reuse our test values from above
- cotp.Secret = "2SH3V3GDW7ZNMGYE"
- cotp.WindowSize = 5
-
- var windowTest = []struct {
- code int
- t0 int
- result bool
- }{
- {50548, 9997, false},
- {50548, 9998, true},
- {50548, 9999, true},
- {50548, 10000, true},
- {50548, 10001, true},
- {50548, 10002, true},
- {50548, 10003, false},
- }
-
- for i, s := range windowTest {
- r := cotp.checkTotpCode(s.t0, s.code)
- if r != s.result {
- t.Errorf("counterCode(%d) (step %d) failed: got %t expected %t", s.code, i, r, s.result)
- }
- }
-
- cotp.DisallowReuse = make([]int, 0)
- var noreuseTest = []struct {
- code int
- t0 int
- result bool
- disallowed []int
- }{
- {50548 /* 10000 */, 9997, false, []int{}},
- {50548 /* 10000 */, 9998, true, []int{10000}},
- {50548 /* 10000 */, 9999, false, []int{10000}},
- {478726 /* 10001 */, 10001, true, []int{10000, 10001}},
- {646986 /* 10002 */, 10002, true, []int{10000, 10001, 10002}},
- {842639 /* 10003 */, 10003, true, []int{10001, 10002, 10003}},
- }
-
- for i, s := range noreuseTest {
- r := cotp.checkTotpCode(s.t0, s.code)
- if r != s.result {
- t.Errorf("timeCode(%d) (step %d) failed: got %t expected %t", s.code, i, r, s.result)
- }
- if len(cotp.DisallowReuse) != len(s.disallowed) {
- t.Errorf("timeCode(%d) (step %d) failed: disallowReuse len mismatch: got %d expected %d", s.code, i, len(cotp.DisallowReuse), len(s.disallowed))
- } else {
- same := true
- for j := range s.disallowed {
- if s.disallowed[j] != cotp.DisallowReuse[j] {
- same = false
- }
- }
- if !same {
- t.Errorf("timeCode(%d) (step %d) failed: disallowReused: got %v expected %v", s.code, i, cotp.DisallowReuse, s.disallowed)
- }
- }
- }
-}
-
-func TestAuthenticate(t *testing.T) {
-
- otpconf := &OTPConfig{
- Secret: "2SH3V3GDW7ZNMGYE",
- WindowSize: 3,
- HotpCounter: 1,
- ScratchCodes: []int{11112222, 22223333},
- }
-
- type attempt struct {
- code string
- result bool
- }
-
- var attempts = []attempt{
- {"foobar", false}, // not digits
- {"1fooba", false}, // not valid number
- {"1111111", false}, // bad length
- { /* 1 */ "293240", true}, // hopt increments on success
- { /* 1 */ "293240", false}, // hopt failure
- {"33334444", false}, // scratch
- {"11112222", true},
- {"11112222", false},
- }
-
- for _, a := range attempts {
- r, _ := otpconf.Authenticate(a.code)
- if r != a.result {
- t.Errorf("bad result from code=%s: got %t expected %t\n", a.code, r, a.result)
- }
- }
-
- // let's check some time-based codes
- otpconf.HotpCounter = 0
- // I haven't mocked the clock, so we'll just compute one
- var t0 int64
- if otpconf.UTC {
- t0 = int64(time.Now().UTC().Unix() / 30)
- } else {
- t0 = int64(time.Now().Unix() / 30)
- }
- c := ComputeCode(otpconf.Secret, t0)
-
- invalid := c + 1
- attempts = []attempt{
- {strconv.Itoa(invalid), false},
- {strconv.Itoa(c), true},
- }
-
- for _, a := range attempts {
- r, _ := otpconf.Authenticate(a.code)
- if r != a.result {
- t.Errorf("bad result from code=%s: got %t expected %t\n", a.code, r, a.result)
- }
-
- otpconf.UTC = true
- r, _ = otpconf.Authenticate(a.code)
- if r != a.result {
- t.Errorf("bad result from code=%s: got %t expected %t\n", a.code, r, a.result)
- }
- otpconf.UTC = false
- }
-
-}
-
-func TestProvisionURI(t *testing.T) {
- otpconf := OTPConfig{
- Secret: "x",
- }
-
- cases := []struct {
- user, iss string
- hotp bool
- out string
- }{
- {"test", "", false, "otpauth://totp/test?secret=x"},
- {"test", "", true, "otpauth://hotp/test?counter=1&secret=x"},
- {"test", "Company", true, "otpauth://hotp/Company:test?counter=1&issuer=Company&secret=x"},
- {"test", "Company", false, "otpauth://totp/Company:test?issuer=Company&secret=x"},
- }
-
- for i, c := range cases {
- otpconf.HotpCounter = 0
- if c.hotp {
- otpconf.HotpCounter = 1
- }
- got := otpconf.ProvisionURIWithIssuer(c.user, c.iss)
- if got != c.out {
- t.Errorf("%d: want %q, got %q", i, c.out, got)
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE b/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE
deleted file mode 100644
index 95ae410c3..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2012-2014 Grigory Dryapak
-
-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. \ No newline at end of file
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/README.md b/Godeps/_workspace/src/github.com/disintegration/imaging/README.md
deleted file mode 100644
index 25d836cef..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/README.md
+++ /dev/null
@@ -1,194 +0,0 @@
-# Imaging
-
-Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
-This package is based on the standard Go image package and works best along with it.
-
-Image manipulation functions provided by the package take any image type
-that implements `image.Image` interface as an input, and return a new image of
-`*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha).
-
-## Installation
-
-Imaging requires Go version 1.2 or greater.
-
- go get -u github.com/disintegration/imaging
-
-## Documentation
-
-http://godoc.org/github.com/disintegration/imaging
-
-## Usage examples
-
-A few usage examples can be found below. See the documentation for the full list of supported functions.
-
-### Image resizing
-```go
-// resize srcImage to size = 128x128px using the Lanczos filter
-dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
-
-// resize srcImage to width = 800px preserving the aspect ratio
-dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
-
-// scale down srcImage to fit the 800x600px bounding box
-dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
-
-// resize and crop the srcImage to fill the 100x100px area
-dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-
-Imaging supports image resizing using various resampling filters. The most notable ones:
-- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
-- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
-- `Linear` - Bilinear filter, smooth and reasonably fast.
-- `MitchellNetravali` - Ð smooth bicubic filter.
-- `CatmullRom` - A sharp bicubic filter.
-- `Gaussian` - Blurring filter that uses gaussian function, useful for noise removal.
-- `Lanczos` - High-quality resampling filter for photographic images yielding sharp results, but it's slower than cubic filters.
-
-The full list of supported filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
-
-**Resampling filters comparison**
-
-Original image. Will be resized from 512x512px to 128x128px.
-
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_512.png)
-
-Filter | Resize result
----|---
-`imaging.NearestNeighbor` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_nearest.png)
-`imaging.Box` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_box.png)
-`imaging.Linear` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_linear.png)
-`imaging.MitchellNetravali` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_mitchell.png)
-`imaging.CatmullRom` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_catrom.png)
-`imaging.Gaussian` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_gaussian.png)
-`imaging.Lanczos` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_lanczos.png)
-
-**Resize functions comparison**
-
-Original image:
-
-![srcImage](http://disintegration.github.io/imaging/in.jpg)
-
-Resize the image to width=100px and height=100px:
-
-```go
-dstImage := imaging.Resize(srcImage, 100, 100, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-resize.jpg)
-
-Resize the image to width=100px preserving the aspect ratio:
-
-```go
-dstImage := imaging.Resize(srcImage, 100, 0, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fit.jpg)
-
-Resize the image to fit the 100x100px boundng box preserving the aspect ratio:
-
-```go
-dstImage := imaging.Fit(srcImage, 100, 100, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fit.jpg)
-
-Resize and crop the image with a center anchor point to fill the 100x100px area:
-
-```go
-dstImage := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fill.jpg)
-
-### Gaussian Blur
-```go
-dstImage := imaging.Blur(srcImage, 0.5)
-```
-
-Sigma parameter allows to control the strength of the blurring effect.
-
-Original image | Sigma = 0.5 | Sigma = 1.5
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_blur_0.5.png) | ![dstImage](http://disintegration.github.io/imaging/out_blur_1.5.png)
-
-### Sharpening
-```go
-dstImage := imaging.Sharpen(srcImage, 0.5)
-```
-
-Uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
-
-Original image | Sigma = 0.5 | Sigma = 1.5
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_sharpen_0.5.png) | ![dstImage](http://disintegration.github.io/imaging/out_sharpen_1.5.png)
-
-### Gamma correction
-```go
-dstImage := imaging.AdjustGamma(srcImage, 0.75)
-```
-
-Original image | Gamma = 0.75 | Gamma = 1.25
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_gamma_0.75.png) | ![dstImage](http://disintegration.github.io/imaging/out_gamma_1.25.png)
-
-### Contrast adjustment
-```go
-dstImage := imaging.AdjustContrast(srcImage, 20)
-```
-
-Original image | Contrast = 20 | Contrast = -20
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_contrast_p20.png) | ![dstImage](http://disintegration.github.io/imaging/out_contrast_m20.png)
-
-### Brightness adjustment
-```go
-dstImage := imaging.AdjustBrightness(srcImage, 20)
-```
-
-Original image | Brightness = 20 | Brightness = -20
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_brightness_p20.png) | ![dstImage](http://disintegration.github.io/imaging/out_brightness_m20.png)
-
-
-### Complete code example
-Here is the code example that loads several images, makes thumbnails of them
-and combines them together side-by-side.
-
-```go
-package main
-
-import (
- "image"
- "image/color"
-
- "github.com/disintegration/imaging"
-)
-
-func main() {
-
- // input files
- files := []string{"01.jpg", "02.jpg", "03.jpg"}
-
- // load images and make 100x100 thumbnails of them
- var thumbnails []image.Image
- for _, file := range files {
- img, err := imaging.Open(file)
- if err != nil {
- panic(err)
- }
- thumb := imaging.Thumbnail(img, 100, 100, imaging.CatmullRom)
- thumbnails = append(thumbnails, thumb)
- }
-
- // create a new blank image
- dst := imaging.New(100*len(thumbnails), 100, color.NRGBA{0, 0, 0, 0})
-
- // paste thumbnails into the new image side by side
- for i, thumb := range thumbnails {
- dst = imaging.Paste(dst, thumb, image.Pt(i*100, 0))
- }
-
- // save the combined image to file
- err := imaging.Save(dst, "dst.jpg")
- if err != nil {
- panic(err)
- }
-}
-```
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go b/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go
deleted file mode 100644
index 9b1b83a4f..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go
+++ /dev/null
@@ -1,200 +0,0 @@
-package imaging
-
-import (
- "image"
- "image/color"
- "math"
-)
-
-// AdjustFunc applies the fn function to each pixel of the img image and returns the adjusted image.
-//
-// Example:
-//
-// dstImage = imaging.AdjustFunc(
-// srcImage,
-// func(c color.NRGBA) color.NRGBA {
-// // shift the red channel by 16
-// r := int(c.R) + 16
-// if r > 255 {
-// r = 255
-// }
-// return color.NRGBA{uint8(r), c.G, c.B, c.A}
-// }
-// )
-//
-func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA {
- src := toNRGBA(img)
- width := src.Bounds().Max.X
- height := src.Bounds().Max.Y
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
-
- parallel(height, func(partStart, partEnd int) {
- for y := partStart; y < partEnd; y++ {
- for x := 0; x < width; x++ {
- i := y*src.Stride + x*4
- j := y*dst.Stride + x*4
-
- r := src.Pix[i+0]
- g := src.Pix[i+1]
- b := src.Pix[i+2]
- a := src.Pix[i+3]
-
- c := fn(color.NRGBA{r, g, b, a})
-
- dst.Pix[j+0] = c.R
- dst.Pix[j+1] = c.G
- dst.Pix[j+2] = c.B
- dst.Pix[j+3] = c.A
- }
- }
- })
-
- return dst
-}
-
-// AdjustGamma performs a gamma correction on the image and returns the adjusted image.
-// Gamma parameter must be positive. Gamma = 1.0 gives the original image.
-// Gamma less than 1.0 darkens the image and gamma greater than 1.0 lightens it.
-//
-// Example:
-//
-// dstImage = imaging.AdjustGamma(srcImage, 0.7)
-//
-func AdjustGamma(img image.Image, gamma float64) *image.NRGBA {
- e := 1.0 / math.Max(gamma, 0.0001)
- lut := make([]uint8, 256)
-
- for i := 0; i < 256; i++ {
- lut[i] = clamp(math.Pow(float64(i)/255.0, e) * 255.0)
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-func sigmoid(a, b, x float64) float64 {
- return 1 / (1 + math.Exp(b*(a-x)))
-}
-
-// AdjustSigmoid changes the contrast of the image using a sigmoidal function and returns the adjusted image.
-// It's a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail.
-// The midpoint parameter is the midpoint of contrast that must be between 0 and 1, typically 0.5.
-// The factor parameter indicates how much to increase or decrease the contrast, typically in range (-10, 10).
-// If the factor parameter is positive the image contrast is increased otherwise the contrast is decreased.
-//
-// Examples:
-//
-// dstImage = imaging.AdjustSigmoid(srcImage, 0.5, 3.0) // increase the contrast
-// dstImage = imaging.AdjustSigmoid(srcImage, 0.5, -3.0) // decrease the contrast
-//
-func AdjustSigmoid(img image.Image, midpoint, factor float64) *image.NRGBA {
- if factor == 0 {
- return Clone(img)
- }
-
- lut := make([]uint8, 256)
- a := math.Min(math.Max(midpoint, 0.0), 1.0)
- b := math.Abs(factor)
- sig0 := sigmoid(a, b, 0)
- sig1 := sigmoid(a, b, 1)
- e := 1.0e-6
-
- if factor > 0 {
- for i := 0; i < 256; i++ {
- x := float64(i) / 255.0
- sigX := sigmoid(a, b, x)
- f := (sigX - sig0) / (sig1 - sig0)
- lut[i] = clamp(f * 255.0)
- }
- } else {
- for i := 0; i < 256; i++ {
- x := float64(i) / 255.0
- arg := math.Min(math.Max((sig1-sig0)*x+sig0, e), 1.0-e)
- f := a - math.Log(1.0/arg-1.0)/b
- lut[i] = clamp(f * 255.0)
- }
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-// AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image.
-// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
-// The percentage = -100 gives solid grey image.
-//
-// Examples:
-//
-// dstImage = imaging.AdjustContrast(srcImage, -10) // decrease image contrast by 10%
-// dstImage = imaging.AdjustContrast(srcImage, 20) // increase image contrast by 20%
-//
-func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
- percentage = math.Min(math.Max(percentage, -100.0), 100.0)
- lut := make([]uint8, 256)
-
- v := (100.0 + percentage) / 100.0
- for i := 0; i < 256; i++ {
- if 0 <= v && v <= 1 {
- lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*v) * 255.0)
- } else if 1 < v && v < 2 {
- lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*(1/(2.0-v))) * 255.0)
- } else {
- lut[i] = uint8(float64(i)/255.0+0.5) * 255
- }
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-// AdjustBrightness changes the brightness of the image using the percentage parameter and returns the adjusted image.
-// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
-// The percentage = -100 gives solid black image. The percentage = 100 gives solid white image.
-//
-// Examples:
-//
-// dstImage = imaging.AdjustBrightness(srcImage, -15) // decrease image brightness by 15%
-// dstImage = imaging.AdjustBrightness(srcImage, 10) // increase image brightness by 10%
-//
-func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
- percentage = math.Min(math.Max(percentage, -100.0), 100.0)
- lut := make([]uint8, 256)
-
- shift := 255.0 * percentage / 100.0
- for i := 0; i < 256; i++ {
- lut[i] = clamp(float64(i) + shift)
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-// Grayscale produces grayscale version of the image.
-func Grayscale(img image.Image) *image.NRGBA {
- fn := func(c color.NRGBA) color.NRGBA {
- f := 0.299*float64(c.R) + 0.587*float64(c.G) + 0.114*float64(c.B)
- y := uint8(f + 0.5)
- return color.NRGBA{y, y, y, c.A}
- }
- return AdjustFunc(img, fn)
-}
-
-// Invert produces inverted (negated) version of the image.
-func Invert(img image.Image) *image.NRGBA {
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{255 - c.R, 255 - c.G, 255 - c.B, c.A}
- }
- return AdjustFunc(img, fn)
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go b/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go
deleted file mode 100644
index fe92e10a2..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go
+++ /dev/null
@@ -1,187 +0,0 @@
-package imaging
-
-import (
- "image"
- "math"
-)
-
-func gaussianBlurKernel(x, sigma float64) float64 {
- return math.Exp(-(x*x)/(2*sigma*sigma)) / (sigma * math.Sqrt(2*math.Pi))
-}
-
-// Blur produces a blurred version of the image using a Gaussian function.
-// Sigma parameter must be positive and indicates how much the image will be blurred.
-//
-// Usage example:
-//
-// dstImage := imaging.Blur(srcImage, 3.5)
-//
-func Blur(img image.Image, sigma float64) *image.NRGBA {
- if sigma <= 0 {
- // sigma parameter must be positive!
- return Clone(img)
- }
-
- src := toNRGBA(img)
- radius := int(math.Ceil(sigma * 3.0))
- kernel := make([]float64, radius+1)
-
- for i := 0; i <= radius; i++ {
- kernel[i] = gaussianBlurKernel(float64(i), sigma)
- }
-
- var dst *image.NRGBA
- dst = blurHorizontal(src, kernel)
- dst = blurVertical(dst, kernel)
-
- return dst
-}
-
-func blurHorizontal(src *image.NRGBA, kernel []float64) *image.NRGBA {
- radius := len(kernel) - 1
- width := src.Bounds().Max.X
- height := src.Bounds().Max.Y
-
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
-
- parallel(width, func(partStart, partEnd int) {
- for x := partStart; x < partEnd; x++ {
- start := x - radius
- if start < 0 {
- start = 0
- }
-
- end := x + radius
- if end > width-1 {
- end = width - 1
- }
-
- weightSum := 0.0
- for ix := start; ix <= end; ix++ {
- weightSum += kernel[absint(x-ix)]
- }
-
- for y := 0; y < height; y++ {
-
- r, g, b, a := 0.0, 0.0, 0.0, 0.0
- for ix := start; ix <= end; ix++ {
- weight := kernel[absint(x-ix)]
- i := y*src.Stride + ix*4
- r += float64(src.Pix[i+0]) * weight
- g += float64(src.Pix[i+1]) * weight
- b += float64(src.Pix[i+2]) * weight
- a += float64(src.Pix[i+3]) * weight
- }
-
- r = math.Min(math.Max(r/weightSum, 0.0), 255.0)
- g = math.Min(math.Max(g/weightSum, 0.0), 255.0)
- b = math.Min(math.Max(b/weightSum, 0.0), 255.0)
- a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
-
- j := y*dst.Stride + x*4
- dst.Pix[j+0] = uint8(r + 0.5)
- dst.Pix[j+1] = uint8(g + 0.5)
- dst.Pix[j+2] = uint8(b + 0.5)
- dst.Pix[j+3] = uint8(a + 0.5)
-
- }
- }
- })
-
- return dst
-}
-
-func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA {
- radius := len(kernel) - 1
- width := src.Bounds().Max.X
- height := src.Bounds().Max.Y
-
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
-
- parallel(height, func(partStart, partEnd int) {
- for y := partStart; y < partEnd; y++ {
- start := y - radius
- if start < 0 {
- start = 0
- }
-
- end := y + radius
- if end > height-1 {
- end = height - 1
- }
-
- weightSum := 0.0
- for iy := start; iy <= end; iy++ {
- weightSum += kernel[absint(y-iy)]
- }
-
- for x := 0; x < width; x++ {
-
- r, g, b, a := 0.0, 0.0, 0.0, 0.0
- for iy := start; iy <= end; iy++ {
- weight := kernel[absint(y-iy)]
- i := iy*src.Stride + x*4
- r += float64(src.Pix[i+0]) * weight
- g += float64(src.Pix[i+1]) * weight
- b += float64(src.Pix[i+2]) * weight
- a += float64(src.Pix[i+3]) * weight
- }
-
- r = math.Min(math.Max(r/weightSum, 0.0), 255.0)
- g = math.Min(math.Max(g/weightSum, 0.0), 255.0)
- b = math.Min(math.Max(b/weightSum, 0.0), 255.0)
- a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
-
- j := y*dst.Stride + x*4
- dst.Pix[j+0] = uint8(r + 0.5)
- dst.Pix[j+1] = uint8(g + 0.5)
- dst.Pix[j+2] = uint8(b + 0.5)
- dst.Pix[j+3] = uint8(a + 0.5)
-
- }
- }
- })
-
- return dst
-}
-
-// Sharpen produces a sharpened version of the image.
-// Sigma parameter must be positive and indicates how much the image will be sharpened.
-//
-// Usage example:
-//
-// dstImage := imaging.Sharpen(srcImage, 3.5)
-//
-func Sharpen(img image.Image, sigma float64) *image.NRGBA {
- if sigma <= 0 {
- // sigma parameter must be positive!
- return Clone(img)
- }
-
- src := toNRGBA(img)
- blurred := Blur(img, sigma)
-
- width := src.Bounds().Max.X
- height := src.Bounds().Max.Y
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
-
- parallel(height, func(partStart, partEnd int) {
- for y := partStart; y < partEnd; y++ {
- for x := 0; x < width; x++ {
- i := y*src.Stride + x*4
- for j := 0; j < 4; j++ {
- k := i + j
- val := int(src.Pix[k]) + (int(src.Pix[k]) - int(blurred.Pix[k]))
- if val < 0 {
- val = 0
- } else if val > 255 {
- val = 255
- }
- dst.Pix[k] = uint8(val)
- }
- }
- }
- })
-
- return dst
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go b/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go
deleted file mode 100644
index 79967ae44..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
-Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
-This package is based on the standard Go image package and works best along with it.
-
-Image manipulation functions provided by the package take any image type
-that implements `image.Image` interface as an input, and return a new image of
-`*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha).
-*/
-package imaging
-
-import (
- "errors"
- "image"
- "image/color"
- "image/gif"
- "image/jpeg"
- "image/png"
- "io"
- "os"
- "path/filepath"
- "strings"
-
- "golang.org/x/image/bmp"
- "golang.org/x/image/tiff"
-)
-
-type Format int
-
-const (
- JPEG Format = iota
- PNG
- GIF
- TIFF
- BMP
-)
-
-func (f Format) String() string {
- switch f {
- case JPEG:
- return "JPEG"
- case PNG:
- return "PNG"
- case GIF:
- return "GIF"
- case TIFF:
- return "TIFF"
- case BMP:
- return "BMP"
- default:
- return "Unsupported"
- }
-}
-
-var (
- ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
-)
-
-// Decode reads an image from r.
-func Decode(r io.Reader) (image.Image, error) {
- img, _, err := image.Decode(r)
- if err != nil {
- return nil, err
- }
- return toNRGBA(img), nil
-}
-
-// Open loads an image from file
-func Open(filename string) (image.Image, error) {
- file, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- img, err := Decode(file)
- return img, err
-}
-
-// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
-func Encode(w io.Writer, img image.Image, format Format) error {
- var err error
- switch format {
- case JPEG:
- var rgba *image.RGBA
- if nrgba, ok := img.(*image.NRGBA); ok {
- if nrgba.Opaque() {
- rgba = &image.RGBA{
- Pix: nrgba.Pix,
- Stride: nrgba.Stride,
- Rect: nrgba.Rect,
- }
- }
- }
- if rgba != nil {
- err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: 95})
- } else {
- err = jpeg.Encode(w, img, &jpeg.Options{Quality: 95})
- }
-
- case PNG:
- err = png.Encode(w, img)
- case GIF:
- err = gif.Encode(w, img, &gif.Options{NumColors: 256})
- case TIFF:
- err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
- case BMP:
- err = bmp.Encode(w, img)
- default:
- err = ErrUnsupportedFormat
- }
- return err
-}
-
-// Save saves the image to file with the specified filename.
-// The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
-func Save(img image.Image, filename string) (err error) {
- formats := map[string]Format{
- ".jpg": JPEG,
- ".jpeg": JPEG,
- ".png": PNG,
- ".tif": TIFF,
- ".tiff": TIFF,
- ".bmp": BMP,
- ".gif": GIF,
- }
-
- ext := strings.ToLower(filepath.Ext(filename))
- f, ok := formats[ext]
- if !ok {
- return ErrUnsupportedFormat
- }
-
- file, err := os.Create(filename)
- if err != nil {
- return err
- }
- defer file.Close()
-
- return Encode(file, img, f)
-}
-
-// New creates a new image with the specified width and height, and fills it with the specified color.
-func New(width, height int, fillColor color.Color) *image.NRGBA {
- if width <= 0 || height <= 0 {
- return &image.NRGBA{}
- }
-
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
- c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
-
- if c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0 {
- return dst
- }
-
- cs := []uint8{c.R, c.G, c.B, c.A}
-
- // fill the first row
- for x := 0; x < width; x++ {
- copy(dst.Pix[x*4:(x+1)*4], cs)
- }
- // copy the first row to other rows
- for y := 1; y < height; y++ {
- copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4])
- }
-
- return dst
-}
-
-// Clone returns a copy of the given image.
-func Clone(img image.Image) *image.NRGBA {
- srcBounds := img.Bounds()
- srcMinX := srcBounds.Min.X
- srcMinY := srcBounds.Min.Y
-
- dstBounds := srcBounds.Sub(srcBounds.Min)
- dstW := dstBounds.Dx()
- dstH := dstBounds.Dy()
- dst := image.NewNRGBA(dstBounds)
-
- switch src := img.(type) {
-
- case *image.NRGBA:
- rowSize := srcBounds.Dx() * 4
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize])
- }
- })
-
- case *image.NRGBA64:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- dst.Pix[di+0] = src.Pix[si+0]
- dst.Pix[di+1] = src.Pix[si+2]
- dst.Pix[di+2] = src.Pix[si+4]
- dst.Pix[di+3] = src.Pix[si+6]
-
- di += 4
- si += 8
-
- }
- }
- })
-
- case *image.RGBA:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- a := src.Pix[si+3]
- dst.Pix[di+3] = a
- switch a {
- case 0:
- dst.Pix[di+0] = 0
- dst.Pix[di+1] = 0
- dst.Pix[di+2] = 0
- case 0xff:
- dst.Pix[di+0] = src.Pix[si+0]
- dst.Pix[di+1] = src.Pix[si+1]
- dst.Pix[di+2] = src.Pix[si+2]
- default:
- var tmp uint16
- tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
- dst.Pix[di+0] = uint8(tmp)
- tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a)
- dst.Pix[di+1] = uint8(tmp)
- tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
- dst.Pix[di+2] = uint8(tmp)
- }
-
- di += 4
- si += 4
-
- }
- }
- })
-
- case *image.RGBA64:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- a := src.Pix[si+6]
- dst.Pix[di+3] = a
- switch a {
- case 0:
- dst.Pix[di+0] = 0
- dst.Pix[di+1] = 0
- dst.Pix[di+2] = 0
- case 0xff:
- dst.Pix[di+0] = src.Pix[si+0]
- dst.Pix[di+1] = src.Pix[si+2]
- dst.Pix[di+2] = src.Pix[si+4]
- default:
- var tmp uint16
- tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
- dst.Pix[di+0] = uint8(tmp)
- tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
- dst.Pix[di+1] = uint8(tmp)
- tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a)
- dst.Pix[di+2] = uint8(tmp)
- }
-
- di += 4
- si += 8
-
- }
- }
- })
-
- case *image.Gray:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- c := src.Pix[si]
- dst.Pix[di+0] = c
- dst.Pix[di+1] = c
- dst.Pix[di+2] = c
- dst.Pix[di+3] = 0xff
-
- di += 4
- si += 1
-
- }
- }
- })
-
- case *image.Gray16:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- c := src.Pix[si]
- dst.Pix[di+0] = c
- dst.Pix[di+1] = c
- dst.Pix[di+2] = c
- dst.Pix[di+3] = 0xff
-
- di += 4
- si += 2
-
- }
- }
- })
-
- case *image.YCbCr:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- srcX := srcMinX + dstX
- srcY := srcMinY + dstY
- siy := src.YOffset(srcX, srcY)
- sic := src.COffset(srcX, srcY)
- r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic])
- dst.Pix[di+0] = r
- dst.Pix[di+1] = g
- dst.Pix[di+2] = b
- dst.Pix[di+3] = 0xff
-
- di += 4
-
- }
- }
- })
-
- case *image.Paletted:
- plen := len(src.Palette)
- pnew := make([]color.NRGBA, plen)
- for i := 0; i < plen; i++ {
- pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
- }
-
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- si := src.PixOffset(srcMinX, srcMinY+dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- c := pnew[src.Pix[si]]
- dst.Pix[di+0] = c.R
- dst.Pix[di+1] = c.G
- dst.Pix[di+2] = c.B
- dst.Pix[di+3] = c.A
-
- di += 4
- si += 1
-
- }
- }
- })
-
- default:
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- di := dst.PixOffset(0, dstY)
- for dstX := 0; dstX < dstW; dstX++ {
-
- c := color.NRGBAModel.Convert(img.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
- dst.Pix[di+0] = c.R
- dst.Pix[di+1] = c.G
- dst.Pix[di+2] = c.B
- dst.Pix[di+3] = c.A
-
- di += 4
-
- }
- }
- })
-
- }
-
- return dst
-}
-
-// This function used internally to convert any image type to NRGBA if needed.
-func toNRGBA(img image.Image) *image.NRGBA {
- srcBounds := img.Bounds()
- if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
- if src0, ok := img.(*image.NRGBA); ok {
- return src0
- }
- }
- return Clone(img)
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go b/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go
deleted file mode 100644
index 3c792e904..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go
+++ /dev/null
@@ -1,583 +0,0 @@
-package imaging
-
-import (
- "image"
- "math"
-)
-
-type iwpair struct {
- i int
- w int32
-}
-
-type pweights struct {
- iwpairs []iwpair
- wsum int32
-}
-
-func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) []pweights {
- du := float64(srcSize) / float64(dstSize)
- scale := du
- if scale < 1.0 {
- scale = 1.0
- }
- ru := math.Ceil(scale * filter.Support)
-
- out := make([]pweights, dstSize)
-
- for v := 0; v < dstSize; v++ {
- fu := (float64(v)+0.5)*du - 0.5
-
- startu := int(math.Ceil(fu - ru))
- if startu < 0 {
- startu = 0
- }
- endu := int(math.Floor(fu + ru))
- if endu > srcSize-1 {
- endu = srcSize - 1
- }
-
- wsum := int32(0)
- for u := startu; u <= endu; u++ {
- w := int32(0xff * filter.Kernel((float64(u)-fu)/scale))
- if w != 0 {
- wsum += w
- out[v].iwpairs = append(out[v].iwpairs, iwpair{u, w})
- }
- }
- out[v].wsum = wsum
- }
-
- return out
-}
-
-// Resize resizes the image to the specified width and height using the specified resampling
-// filter and returns the transformed image. If one of width or height is 0, the image aspect
-// ratio is preserved.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// Usage example:
-//
-// dstImage := imaging.Resize(srcImage, 800, 600, imaging.Lanczos)
-//
-func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
- dstW, dstH := width, height
-
- if dstW < 0 || dstH < 0 {
- return &image.NRGBA{}
- }
- if dstW == 0 && dstH == 0 {
- return &image.NRGBA{}
- }
-
- src := toNRGBA(img)
-
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
-
- if srcW <= 0 || srcH <= 0 {
- return &image.NRGBA{}
- }
-
- // if new width or height is 0 then preserve aspect ratio, minimum 1px
- if dstW == 0 {
- tmpW := float64(dstH) * float64(srcW) / float64(srcH)
- dstW = int(math.Max(1.0, math.Floor(tmpW+0.5)))
- }
- if dstH == 0 {
- tmpH := float64(dstW) * float64(srcH) / float64(srcW)
- dstH = int(math.Max(1.0, math.Floor(tmpH+0.5)))
- }
-
- var dst *image.NRGBA
-
- if filter.Support <= 0.0 {
- // nearest-neighbor special case
- dst = resizeNearest(src, dstW, dstH)
-
- } else {
- // two-pass resize
- if srcW != dstW {
- dst = resizeHorizontal(src, dstW, filter)
- } else {
- dst = src
- }
-
- if srcH != dstH {
- dst = resizeVertical(dst, dstH, filter)
- }
- }
-
- return dst
-}
-
-func resizeHorizontal(src *image.NRGBA, width int, filter ResampleFilter) *image.NRGBA {
- srcBounds := src.Bounds()
- srcW := srcBounds.Max.X
- srcH := srcBounds.Max.Y
-
- dstW := width
- dstH := srcH
-
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- weights := precomputeWeights(dstW, srcW, filter)
-
- parallel(dstH, func(partStart, partEnd int) {
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- var c [4]int32
- for _, iw := range weights[dstX].iwpairs {
- i := dstY*src.Stride + iw.i*4
- c[0] += int32(src.Pix[i+0]) * iw.w
- c[1] += int32(src.Pix[i+1]) * iw.w
- c[2] += int32(src.Pix[i+2]) * iw.w
- c[3] += int32(src.Pix[i+3]) * iw.w
- }
- j := dstY*dst.Stride + dstX*4
- sum := weights[dstX].wsum
- dst.Pix[j+0] = clampint32(int32(float32(c[0])/float32(sum) + 0.5))
- dst.Pix[j+1] = clampint32(int32(float32(c[1])/float32(sum) + 0.5))
- dst.Pix[j+2] = clampint32(int32(float32(c[2])/float32(sum) + 0.5))
- dst.Pix[j+3] = clampint32(int32(float32(c[3])/float32(sum) + 0.5))
- }
- }
- })
-
- return dst
-}
-
-func resizeVertical(src *image.NRGBA, height int, filter ResampleFilter) *image.NRGBA {
- srcBounds := src.Bounds()
- srcW := srcBounds.Max.X
- srcH := srcBounds.Max.Y
-
- dstW := srcW
- dstH := height
-
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- weights := precomputeWeights(dstH, srcH, filter)
-
- parallel(dstW, func(partStart, partEnd int) {
-
- for dstX := partStart; dstX < partEnd; dstX++ {
- for dstY := 0; dstY < dstH; dstY++ {
- var c [4]int32
- for _, iw := range weights[dstY].iwpairs {
- i := iw.i*src.Stride + dstX*4
- c[0] += int32(src.Pix[i+0]) * iw.w
- c[1] += int32(src.Pix[i+1]) * iw.w
- c[2] += int32(src.Pix[i+2]) * iw.w
- c[3] += int32(src.Pix[i+3]) * iw.w
- }
- j := dstY*dst.Stride + dstX*4
- sum := weights[dstY].wsum
- dst.Pix[j+0] = clampint32(int32(float32(c[0])/float32(sum) + 0.5))
- dst.Pix[j+1] = clampint32(int32(float32(c[1])/float32(sum) + 0.5))
- dst.Pix[j+2] = clampint32(int32(float32(c[2])/float32(sum) + 0.5))
- dst.Pix[j+3] = clampint32(int32(float32(c[3])/float32(sum) + 0.5))
- }
- }
-
- })
-
- return dst
-}
-
-// fast nearest-neighbor resize, no filtering
-func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA {
- dstW, dstH := width, height
-
- srcBounds := src.Bounds()
- srcW := srcBounds.Max.X
- srcH := srcBounds.Max.Y
-
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- dx := float64(srcW) / float64(dstW)
- dy := float64(srcH) / float64(dstH)
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- fy := (float64(dstY)+0.5)*dy - 0.5
-
- for dstX := 0; dstX < dstW; dstX++ {
- fx := (float64(dstX)+0.5)*dx - 0.5
-
- srcX := int(math.Min(math.Max(math.Floor(fx+0.5), 0.0), float64(srcW)))
- srcY := int(math.Min(math.Max(math.Floor(fy+0.5), 0.0), float64(srcH)))
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// Fit scales down the image using the specified resample filter to fit the specified
-// maximum width and height and returns the transformed image.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// Usage example:
-//
-// dstImage := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
-//
-func Fit(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
- maxW, maxH := width, height
-
- if maxW <= 0 || maxH <= 0 {
- return &image.NRGBA{}
- }
-
- srcBounds := img.Bounds()
- srcW := srcBounds.Dx()
- srcH := srcBounds.Dy()
-
- if srcW <= 0 || srcH <= 0 {
- return &image.NRGBA{}
- }
-
- if srcW <= maxW && srcH <= maxH {
- return Clone(img)
- }
-
- srcAspectRatio := float64(srcW) / float64(srcH)
- maxAspectRatio := float64(maxW) / float64(maxH)
-
- var newW, newH int
- if srcAspectRatio > maxAspectRatio {
- newW = maxW
- newH = int(float64(newW) / srcAspectRatio)
- } else {
- newH = maxH
- newW = int(float64(newH) * srcAspectRatio)
- }
-
- return Resize(img, newW, newH, filter)
-}
-
-// Fill scales the image to the smallest possible size that will cover the specified dimensions,
-// crops the resized image to the specified dimensions using the given anchor point and returns
-// the transformed image.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// Usage example:
-//
-// dstImage := imaging.Fill(srcImage, 800, 600, imaging.Center, imaging.Lanczos)
-//
-func Fill(img image.Image, width, height int, anchor Anchor, filter ResampleFilter) *image.NRGBA {
- minW, minH := width, height
-
- if minW <= 0 || minH <= 0 {
- return &image.NRGBA{}
- }
-
- srcBounds := img.Bounds()
- srcW := srcBounds.Dx()
- srcH := srcBounds.Dy()
-
- if srcW <= 0 || srcH <= 0 {
- return &image.NRGBA{}
- }
-
- if srcW == minW && srcH == minH {
- return Clone(img)
- }
-
- srcAspectRatio := float64(srcW) / float64(srcH)
- minAspectRatio := float64(minW) / float64(minH)
-
- var tmp *image.NRGBA
- if srcAspectRatio < minAspectRatio {
- tmp = Resize(img, minW, 0, filter)
- } else {
- tmp = Resize(img, 0, minH, filter)
- }
-
- return CropAnchor(tmp, minW, minH, anchor)
-}
-
-// Thumbnail scales the image up or down using the specified resample filter, crops it
-// to the specified width and hight and returns the transformed image.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// Usage example:
-//
-// dstImage := imaging.Thumbnail(srcImage, 100, 100, imaging.Lanczos)
-//
-func Thumbnail(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
- return Fill(img, width, height, Center, filter)
-}
-
-// Resample filter struct. It can be used to make custom filters.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// General filter recommendations:
-//
-// - Lanczos
-// Probably the best resampling filter for photographic images yielding sharp results,
-// but it's slower than cubic filters (see below).
-//
-// - CatmullRom
-// A sharp cubic filter. It's a good filter for both upscaling and downscaling if sharp results are needed.
-//
-// - MitchellNetravali
-// A high quality cubic filter that produces smoother results with less ringing than CatmullRom.
-//
-// - BSpline
-// A good filter if a very smooth output is needed.
-//
-// - Linear
-// Bilinear interpolation filter, produces reasonably good, smooth output. It's faster than cubic filters.
-//
-// - Box
-// Simple and fast resampling filter appropriate for downscaling.
-// When upscaling it's similar to NearestNeighbor.
-//
-// - NearestNeighbor
-// Fastest resample filter, no antialiasing at all. Rarely used.
-//
-type ResampleFilter struct {
- Support float64
- Kernel func(float64) float64
-}
-
-// Nearest-neighbor filter, no anti-aliasing.
-var NearestNeighbor ResampleFilter
-
-// Box filter (averaging pixels).
-var Box ResampleFilter
-
-// Linear filter.
-var Linear ResampleFilter
-
-// Hermite cubic spline filter (BC-spline; B=0; C=0).
-var Hermite ResampleFilter
-
-// Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3).
-var MitchellNetravali ResampleFilter
-
-// Catmull-Rom - sharp cubic filter (BC-spline; B=0; C=0.5).
-var CatmullRom ResampleFilter
-
-// Cubic B-spline - smooth cubic filter (BC-spline; B=1; C=0).
-var BSpline ResampleFilter
-
-// Gaussian Blurring Filter.
-var Gaussian ResampleFilter
-
-// Bartlett-windowed sinc filter (3 lobes).
-var Bartlett ResampleFilter
-
-// Lanczos filter (3 lobes).
-var Lanczos ResampleFilter
-
-// Hann-windowed sinc filter (3 lobes).
-var Hann ResampleFilter
-
-// Hamming-windowed sinc filter (3 lobes).
-var Hamming ResampleFilter
-
-// Blackman-windowed sinc filter (3 lobes).
-var Blackman ResampleFilter
-
-// Welch-windowed sinc filter (parabolic window, 3 lobes).
-var Welch ResampleFilter
-
-// Cosine-windowed sinc filter (3 lobes).
-var Cosine ResampleFilter
-
-func bcspline(x, b, c float64) float64 {
- x = math.Abs(x)
- if x < 1.0 {
- return ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6
- }
- if x < 2.0 {
- return ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6
- }
- return 0
-}
-
-func sinc(x float64) float64 {
- if x == 0 {
- return 1
- }
- return math.Sin(math.Pi*x) / (math.Pi * x)
-}
-
-func init() {
- NearestNeighbor = ResampleFilter{
- Support: 0.0, // special case - not applying the filter
- }
-
- Box = ResampleFilter{
- Support: 0.5,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x <= 0.5 {
- return 1.0
- }
- return 0
- },
- }
-
- Linear = ResampleFilter{
- Support: 1.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 1.0 {
- return 1.0 - x
- }
- return 0
- },
- }
-
- Hermite = ResampleFilter{
- Support: 1.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 1.0 {
- return bcspline(x, 0.0, 0.0)
- }
- return 0
- },
- }
-
- MitchellNetravali = ResampleFilter{
- Support: 2.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 2.0 {
- return bcspline(x, 1.0/3.0, 1.0/3.0)
- }
- return 0
- },
- }
-
- CatmullRom = ResampleFilter{
- Support: 2.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 2.0 {
- return bcspline(x, 0.0, 0.5)
- }
- return 0
- },
- }
-
- BSpline = ResampleFilter{
- Support: 2.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 2.0 {
- return bcspline(x, 1.0, 0.0)
- }
- return 0
- },
- }
-
- Gaussian = ResampleFilter{
- Support: 2.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 2.0 {
- return math.Exp(-2 * x * x)
- }
- return 0
- },
- }
-
- Bartlett = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * (3.0 - x) / 3.0
- }
- return 0
- },
- }
-
- Lanczos = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * sinc(x/3.0)
- }
- return 0
- },
- }
-
- Hann = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * (0.5 + 0.5*math.Cos(math.Pi*x/3.0))
- }
- return 0
- },
- }
-
- Hamming = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * (0.54 + 0.46*math.Cos(math.Pi*x/3.0))
- }
- return 0
- },
- }
-
- Blackman = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * (0.42 - 0.5*math.Cos(math.Pi*x/3.0+math.Pi) + 0.08*math.Cos(2.0*math.Pi*x/3.0))
- }
- return 0
- },
- }
-
- Welch = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * (1.0 - (x * x / 9.0))
- }
- return 0
- },
- }
-
- Cosine = ResampleFilter{
- Support: 3.0,
- Kernel: func(x float64) float64 {
- x = math.Abs(x)
- if x < 3.0 {
- return sinc(x) * math.Cos((math.Pi/2.0)*(x/3.0))
- }
- return 0
- },
- }
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go b/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go
deleted file mode 100644
index 2c39c900a..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go
+++ /dev/null
@@ -1,182 +0,0 @@
-package imaging
-
-import (
- "image"
- "math"
-)
-
-// Anchor is the anchor point for image alignment.
-type Anchor int
-
-const (
- Center Anchor = iota
- TopLeft
- Top
- TopRight
- Left
- Right
- BottomLeft
- Bottom
- BottomRight
-)
-
-func anchorPt(b image.Rectangle, w, h int, anchor Anchor) image.Point {
- var x, y int
- switch anchor {
- case TopLeft:
- x = b.Min.X
- y = b.Min.Y
- case Top:
- x = b.Min.X + (b.Dx()-w)/2
- y = b.Min.Y
- case TopRight:
- x = b.Max.X - w
- y = b.Min.Y
- case Left:
- x = b.Min.X
- y = b.Min.Y + (b.Dy()-h)/2
- case Right:
- x = b.Max.X - w
- y = b.Min.Y + (b.Dy()-h)/2
- case BottomLeft:
- x = b.Min.X
- y = b.Max.Y - h
- case Bottom:
- x = b.Min.X + (b.Dx()-w)/2
- y = b.Max.Y - h
- case BottomRight:
- x = b.Max.X - w
- y = b.Max.Y - h
- default:
- x = b.Min.X + (b.Dx()-w)/2
- y = b.Min.Y + (b.Dy()-h)/2
- }
- return image.Pt(x, y)
-}
-
-// Crop cuts out a rectangular region with the specified bounds
-// from the image and returns the cropped image.
-func Crop(img image.Image, rect image.Rectangle) *image.NRGBA {
- src := toNRGBA(img)
- srcRect := rect.Sub(img.Bounds().Min)
- sub := src.SubImage(srcRect)
- return Clone(sub) // New image Bounds().Min point will be (0, 0)
-}
-
-// CropAnchor cuts out a rectangular region with the specified size
-// from the image using the specified anchor point and returns the cropped image.
-func CropAnchor(img image.Image, width, height int, anchor Anchor) *image.NRGBA {
- srcBounds := img.Bounds()
- pt := anchorPt(srcBounds, width, height, anchor)
- r := image.Rect(0, 0, width, height).Add(pt)
- b := srcBounds.Intersect(r)
- return Crop(img, b)
-}
-
-// CropCenter cuts out a rectangular region with the specified size
-// from the center of the image and returns the cropped image.
-func CropCenter(img image.Image, width, height int) *image.NRGBA {
- return CropAnchor(img, width, height, Center)
-}
-
-// Paste pastes the img image to the background image at the specified position and returns the combined image.
-func Paste(background, img image.Image, pos image.Point) *image.NRGBA {
- src := toNRGBA(img)
- dst := Clone(background) // cloned image bounds start at (0, 0)
- startPt := pos.Sub(background.Bounds().Min) // so we should translate start point
- endPt := startPt.Add(src.Bounds().Size())
- pasteBounds := image.Rectangle{startPt, endPt}
-
- if dst.Bounds().Overlaps(pasteBounds) {
- intersectBounds := dst.Bounds().Intersect(pasteBounds)
-
- rowSize := intersectBounds.Dx() * 4
- numRows := intersectBounds.Dy()
-
- srcStartX := intersectBounds.Min.X - pasteBounds.Min.X
- srcStartY := intersectBounds.Min.Y - pasteBounds.Min.Y
-
- i0 := dst.PixOffset(intersectBounds.Min.X, intersectBounds.Min.Y)
- j0 := src.PixOffset(srcStartX, srcStartY)
-
- di := dst.Stride
- dj := src.Stride
-
- for row := 0; row < numRows; row++ {
- copy(dst.Pix[i0:i0+rowSize], src.Pix[j0:j0+rowSize])
- i0 += di
- j0 += dj
- }
- }
-
- return dst
-}
-
-// PasteCenter pastes the img image to the center of the background image and returns the combined image.
-func PasteCenter(background, img image.Image) *image.NRGBA {
- bgBounds := background.Bounds()
- bgW := bgBounds.Dx()
- bgH := bgBounds.Dy()
- bgMinX := bgBounds.Min.X
- bgMinY := bgBounds.Min.Y
-
- centerX := bgMinX + bgW/2
- centerY := bgMinY + bgH/2
-
- x0 := centerX - img.Bounds().Dx()/2
- y0 := centerY - img.Bounds().Dy()/2
-
- return Paste(background, img, image.Pt(x0, y0))
-}
-
-// Overlay draws the img image over the background image at given position
-// and returns the combined image. Opacity parameter is the opacity of the img
-// image layer, used to compose the images, it must be from 0.0 to 1.0.
-//
-// Usage examples:
-//
-// // draw the sprite over the background at position (50, 50)
-// dstImage := imaging.Overlay(backgroundImage, spriteImage, image.Pt(50, 50), 1.0)
-//
-// // blend two opaque images of the same size
-// dstImage := imaging.Overlay(imageOne, imageTwo, image.Pt(0, 0), 0.5)
-//
-func Overlay(background, img image.Image, pos image.Point, opacity float64) *image.NRGBA {
- opacity = math.Min(math.Max(opacity, 0.0), 1.0) // check: 0.0 <= opacity <= 1.0
-
- src := toNRGBA(img)
- dst := Clone(background) // cloned image bounds start at (0, 0)
- startPt := pos.Sub(background.Bounds().Min) // so we should translate start point
- endPt := startPt.Add(src.Bounds().Size())
- pasteBounds := image.Rectangle{startPt, endPt}
-
- if dst.Bounds().Overlaps(pasteBounds) {
- intersectBounds := dst.Bounds().Intersect(pasteBounds)
-
- for y := intersectBounds.Min.Y; y < intersectBounds.Max.Y; y++ {
- for x := intersectBounds.Min.X; x < intersectBounds.Max.X; x++ {
- i := y*dst.Stride + x*4
-
- srcX := x - pasteBounds.Min.X
- srcY := y - pasteBounds.Min.Y
- j := srcY*src.Stride + srcX*4
-
- a1 := float64(dst.Pix[i+3])
- a2 := float64(src.Pix[j+3])
-
- coef2 := opacity * a2 / 255.0
- coef1 := (1 - coef2) * a1 / 255.0
- coefSum := coef1 + coef2
- coef1 /= coefSum
- coef2 /= coefSum
-
- dst.Pix[i+0] = uint8(float64(dst.Pix[i+0])*coef1 + float64(src.Pix[j+0])*coef2)
- dst.Pix[i+1] = uint8(float64(dst.Pix[i+1])*coef1 + float64(src.Pix[j+1])*coef2)
- dst.Pix[i+2] = uint8(float64(dst.Pix[i+2])*coef1 + float64(src.Pix[j+2])*coef2)
- dst.Pix[i+3] = uint8(math.Min(a1+a2*opacity*(255.0-a1)/255.0, 255.0))
- }
- }
- }
-
- return dst
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go b/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go
deleted file mode 100644
index a11601bba..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go
+++ /dev/null
@@ -1,201 +0,0 @@
-package imaging
-
-import (
- "image"
-)
-
-// Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image.
-func Rotate90(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcH
- dstH := srcW
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstH - dstY - 1
- srcY := dstX
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image.
-func Rotate180(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcW
- dstH := srcH
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstW - dstX - 1
- srcY := dstH - dstY - 1
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image.
-func Rotate270(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcH
- dstH := srcW
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstY
- srcY := dstW - dstX - 1
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// FlipH flips the image horizontally (from left to right) and returns the transformed image.
-func FlipH(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcW
- dstH := srcH
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstW - dstX - 1
- srcY := dstY
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// FlipV flips the image vertically (from top to bottom) and returns the transformed image.
-func FlipV(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcW
- dstH := srcH
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstX
- srcY := dstH - dstY - 1
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// Transpose flips the image horizontally and rotates 90 degrees counter-clockwise.
-func Transpose(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcH
- dstH := srcW
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstY
- srcY := dstX
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
-
-// Transverse flips the image vertically and rotates 90 degrees counter-clockwise.
-func Transverse(img image.Image) *image.NRGBA {
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW := srcH
- dstH := srcW
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- parallel(dstH, func(partStart, partEnd int) {
-
- for dstY := partStart; dstY < partEnd; dstY++ {
- for dstX := 0; dstX < dstW; dstX++ {
- srcX := dstH - dstY - 1
- srcY := dstW - dstX - 1
-
- srcOff := srcY*src.Stride + srcX*4
- dstOff := dstY*dst.Stride + dstX*4
-
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- }
- }
-
- })
-
- return dst
-}
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go b/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go
deleted file mode 100644
index 8b1ab8adb..000000000
--- a/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package imaging
-
-import (
- "math"
- "runtime"
- "sync"
- "sync/atomic"
-)
-
-var parallelizationEnabled = true
-
-// if GOMAXPROCS = 1: no goroutines used
-// if GOMAXPROCS > 1: spawn N=GOMAXPROCS workers in separate goroutines
-func parallel(dataSize int, fn func(partStart, partEnd int)) {
- numGoroutines := 1
- partSize := dataSize
-
- if parallelizationEnabled {
- numProcs := runtime.GOMAXPROCS(0)
- if numProcs > 1 {
- numGoroutines = numProcs
- partSize = dataSize / (numGoroutines * 10)
- if partSize < 1 {
- partSize = 1
- }
- }
- }
-
- if numGoroutines == 1 {
- fn(0, dataSize)
- } else {
- var wg sync.WaitGroup
- wg.Add(numGoroutines)
- idx := uint64(0)
-
- for p := 0; p < numGoroutines; p++ {
- go func() {
- defer wg.Done()
- for {
- partStart := int(atomic.AddUint64(&idx, uint64(partSize))) - partSize
- if partStart >= dataSize {
- break
- }
- partEnd := partStart + partSize
- if partEnd > dataSize {
- partEnd = dataSize
- }
- fn(partStart, partEnd)
- }
- }()
- }
-
- wg.Wait()
- }
-}
-
-func absint(i int) int {
- if i < 0 {
- return -i
- }
- return i
-}
-
-// clamp & round float64 to uint8 (0..255)
-func clamp(v float64) uint8 {
- return uint8(math.Min(math.Max(v, 0.0), 255.0) + 0.5)
-}
-
-// clamp int32 to uint8 (0..255)
-func clampint32(v int32) uint8 {
- if v < 0 {
- return 0
- } else if v > 255 {
- return 255
- }
- return uint8(v)
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/LICENSE b/Godeps/_workspace/src/github.com/garyburd/redigo/LICENSE
deleted file mode 100644
index 67db85882..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/LICENSE
+++ /dev/null
@@ -1,175 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go b/Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go
deleted file mode 100644
index dbc60fc8e..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// 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 internal
-
-import (
- "strings"
-)
-
-const (
- WatchState = 1 << iota
- MultiState
- SubscribeState
- MonitorState
-)
-
-type CommandInfo struct {
- Set, Clear int
-}
-
-var commandInfos = map[string]CommandInfo{
- "WATCH": {Set: WatchState},
- "UNWATCH": {Clear: WatchState},
- "MULTI": {Set: MultiState},
- "EXEC": {Clear: WatchState | MultiState},
- "DISCARD": {Clear: WatchState | MultiState},
- "PSUBSCRIBE": {Set: SubscribeState},
- "SUBSCRIBE": {Set: SubscribeState},
- "MONITOR": {Set: MonitorState},
-}
-
-func init() {
- for n, ci := range commandInfos {
- commandInfos[strings.ToLower(n)] = ci
- }
-}
-
-func LookupCommandInfo(commandName string) CommandInfo {
- if ci, ok := commandInfos[commandName]; ok {
- return ci
- }
- return commandInfos[strings.ToUpper(commandName)]
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/internal/redistest/testdb.go b/Godeps/_workspace/src/github.com/garyburd/redigo/internal/redistest/testdb.go
deleted file mode 100644
index b6f205b7f..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/internal/redistest/testdb.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// 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 redistest contains utilities for writing Redigo tests.
-package redistest
-
-import (
- "errors"
- "time"
-
- "github.com/garyburd/redigo/redis"
-)
-
-type testConn struct {
- redis.Conn
-}
-
-func (t testConn) Close() error {
- _, err := t.Conn.Do("SELECT", "9")
- if err != nil {
- return nil
- }
- _, err = t.Conn.Do("FLUSHDB")
- if err != nil {
- return err
- }
- return t.Conn.Close()
-}
-
-// Dial dials the local Redis server and selects database 9. To prevent
-// stomping on real data, DialTestDB fails if database 9 contains data. The
-// returned connection flushes database 9 on close.
-func Dial() (redis.Conn, error) {
- c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second)
- if err != nil {
- return nil, err
- }
-
- _, err = c.Do("SELECT", "9")
- if err != nil {
- c.Close()
- return nil, err
- }
-
- n, err := redis.Int(c.Do("DBSIZE"))
- if err != nil {
- c.Close()
- return nil, err
- }
-
- if n != 0 {
- c.Close()
- return nil, errors.New("database #9 is not empty, test can not continue")
- }
-
- return testConn{c}, nil
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn.go
deleted file mode 100644
index 6a3819f1d..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn.go
+++ /dev/null
@@ -1,567 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "net"
- "net/url"
- "regexp"
- "strconv"
- "sync"
- "time"
-)
-
-// conn is the low-level implementation of Conn
-type conn struct {
-
- // Shared
- mu sync.Mutex
- pending int
- err error
- conn net.Conn
-
- // Read
- readTimeout time.Duration
- br *bufio.Reader
-
- // Write
- writeTimeout time.Duration
- bw *bufio.Writer
-
- // Scratch space for formatting argument length.
- // '*' or '$', length, "\r\n"
- lenScratch [32]byte
-
- // Scratch space for formatting integers and floats.
- numScratch [40]byte
-}
-
-// DialTimeout acts like Dial but takes timeouts for establishing the
-// connection to the server, writing a command and reading a reply.
-//
-// Deprecated: Use Dial with options instead.
-func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) {
- return Dial(network, address,
- DialConnectTimeout(connectTimeout),
- DialReadTimeout(readTimeout),
- DialWriteTimeout(writeTimeout))
-}
-
-// DialOption specifies an option for dialing a Redis server.
-type DialOption struct {
- f func(*dialOptions)
-}
-
-type dialOptions struct {
- readTimeout time.Duration
- writeTimeout time.Duration
- dial func(network, addr string) (net.Conn, error)
- db int
- password string
-}
-
-// DialReadTimeout specifies the timeout for reading a single command reply.
-func DialReadTimeout(d time.Duration) DialOption {
- return DialOption{func(do *dialOptions) {
- do.readTimeout = d
- }}
-}
-
-// DialWriteTimeout specifies the timeout for writing a single command.
-func DialWriteTimeout(d time.Duration) DialOption {
- return DialOption{func(do *dialOptions) {
- do.writeTimeout = d
- }}
-}
-
-// DialConnectTimeout specifies the timeout for connecting to the Redis server.
-func DialConnectTimeout(d time.Duration) DialOption {
- return DialOption{func(do *dialOptions) {
- dialer := net.Dialer{Timeout: d}
- do.dial = dialer.Dial
- }}
-}
-
-// DialNetDial specifies a custom dial function for creating TCP
-// connections. If this option is left out, then net.Dial is
-// used. DialNetDial overrides DialConnectTimeout.
-func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
- return DialOption{func(do *dialOptions) {
- do.dial = dial
- }}
-}
-
-// DialDatabase specifies the database to select when dialing a connection.
-func DialDatabase(db int) DialOption {
- return DialOption{func(do *dialOptions) {
- do.db = db
- }}
-}
-
-// DialPassword specifies the password to use when connecting to
-// the Redis server.
-func DialPassword(password string) DialOption {
- return DialOption{func(do *dialOptions) {
- do.password = password
- }}
-}
-
-// Dial connects to the Redis server at the given network and
-// address using the specified options.
-func Dial(network, address string, options ...DialOption) (Conn, error) {
- do := dialOptions{
- dial: net.Dial,
- }
- for _, option := range options {
- option.f(&do)
- }
-
- netConn, err := do.dial(network, address)
- if err != nil {
- return nil, err
- }
- c := &conn{
- conn: netConn,
- bw: bufio.NewWriter(netConn),
- br: bufio.NewReader(netConn),
- readTimeout: do.readTimeout,
- writeTimeout: do.writeTimeout,
- }
-
- if do.password != "" {
- if _, err := c.Do("AUTH", do.password); err != nil {
- netConn.Close()
- return nil, err
- }
- }
-
- if do.db != 0 {
- if _, err := c.Do("SELECT", do.db); err != nil {
- netConn.Close()
- return nil, err
- }
- }
-
- return c, nil
-}
-
-var pathDBRegexp = regexp.MustCompile(`/(\d+)\z`)
-
-// DialURL connects to a Redis server at the given URL using the Redis
-// URI scheme. URLs should follow the draft IANA specification for the
-// scheme (https://www.iana.org/assignments/uri-schemes/prov/redis).
-func DialURL(rawurl string, options ...DialOption) (Conn, error) {
- u, err := url.Parse(rawurl)
- if err != nil {
- return nil, err
- }
-
- if u.Scheme != "redis" {
- return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme)
- }
-
- // As per the IANA draft spec, the host defaults to localhost and
- // the port defaults to 6379.
- host, port, err := net.SplitHostPort(u.Host)
- if err != nil {
- // assume port is missing
- host = u.Host
- port = "6379"
- }
- if host == "" {
- host = "localhost"
- }
- address := net.JoinHostPort(host, port)
-
- if u.User != nil {
- password, isSet := u.User.Password()
- if isSet {
- options = append(options, DialPassword(password))
- }
- }
-
- match := pathDBRegexp.FindStringSubmatch(u.Path)
- if len(match) == 2 {
- db, err := strconv.Atoi(match[1])
- if err != nil {
- return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
- }
- if db != 0 {
- options = append(options, DialDatabase(db))
- }
- } else if u.Path != "" {
- return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
- }
-
- return Dial("tcp", address, options...)
-}
-
-// NewConn returns a new Redigo connection for the given net connection.
-func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn {
- return &conn{
- conn: netConn,
- bw: bufio.NewWriter(netConn),
- br: bufio.NewReader(netConn),
- readTimeout: readTimeout,
- writeTimeout: writeTimeout,
- }
-}
-
-func (c *conn) Close() error {
- c.mu.Lock()
- err := c.err
- if c.err == nil {
- c.err = errors.New("redigo: closed")
- err = c.conn.Close()
- }
- c.mu.Unlock()
- return err
-}
-
-func (c *conn) fatal(err error) error {
- c.mu.Lock()
- if c.err == nil {
- c.err = err
- // Close connection to force errors on subsequent calls and to unblock
- // other reader or writer.
- c.conn.Close()
- }
- c.mu.Unlock()
- return err
-}
-
-func (c *conn) Err() error {
- c.mu.Lock()
- err := c.err
- c.mu.Unlock()
- return err
-}
-
-func (c *conn) writeLen(prefix byte, n int) error {
- c.lenScratch[len(c.lenScratch)-1] = '\n'
- c.lenScratch[len(c.lenScratch)-2] = '\r'
- i := len(c.lenScratch) - 3
- for {
- c.lenScratch[i] = byte('0' + n%10)
- i -= 1
- n = n / 10
- if n == 0 {
- break
- }
- }
- c.lenScratch[i] = prefix
- _, err := c.bw.Write(c.lenScratch[i:])
- return err
-}
-
-func (c *conn) writeString(s string) error {
- c.writeLen('$', len(s))
- c.bw.WriteString(s)
- _, err := c.bw.WriteString("\r\n")
- return err
-}
-
-func (c *conn) writeBytes(p []byte) error {
- c.writeLen('$', len(p))
- c.bw.Write(p)
- _, err := c.bw.WriteString("\r\n")
- return err
-}
-
-func (c *conn) writeInt64(n int64) error {
- return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10))
-}
-
-func (c *conn) writeFloat64(n float64) error {
- return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
-}
-
-func (c *conn) writeCommand(cmd string, args []interface{}) (err error) {
- c.writeLen('*', 1+len(args))
- err = c.writeString(cmd)
- for _, arg := range args {
- if err != nil {
- break
- }
- switch arg := arg.(type) {
- case string:
- err = c.writeString(arg)
- case []byte:
- err = c.writeBytes(arg)
- case int:
- err = c.writeInt64(int64(arg))
- case int64:
- err = c.writeInt64(arg)
- case float64:
- err = c.writeFloat64(arg)
- case bool:
- if arg {
- err = c.writeString("1")
- } else {
- err = c.writeString("0")
- }
- case nil:
- err = c.writeString("")
- default:
- var buf bytes.Buffer
- fmt.Fprint(&buf, arg)
- err = c.writeBytes(buf.Bytes())
- }
- }
- return err
-}
-
-type protocolError string
-
-func (pe protocolError) Error() string {
- return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
-}
-
-func (c *conn) readLine() ([]byte, error) {
- p, err := c.br.ReadSlice('\n')
- if err == bufio.ErrBufferFull {
- return nil, protocolError("long response line")
- }
- if err != nil {
- return nil, err
- }
- i := len(p) - 2
- if i < 0 || p[i] != '\r' {
- return nil, protocolError("bad response line terminator")
- }
- return p[:i], nil
-}
-
-// parseLen parses bulk string and array lengths.
-func parseLen(p []byte) (int, error) {
- if len(p) == 0 {
- return -1, protocolError("malformed length")
- }
-
- if p[0] == '-' && len(p) == 2 && p[1] == '1' {
- // handle $-1 and $-1 null replies.
- return -1, nil
- }
-
- var n int
- for _, b := range p {
- n *= 10
- if b < '0' || b > '9' {
- return -1, protocolError("illegal bytes in length")
- }
- n += int(b - '0')
- }
-
- return n, nil
-}
-
-// parseInt parses an integer reply.
-func parseInt(p []byte) (interface{}, error) {
- if len(p) == 0 {
- return 0, protocolError("malformed integer")
- }
-
- var negate bool
- if p[0] == '-' {
- negate = true
- p = p[1:]
- if len(p) == 0 {
- return 0, protocolError("malformed integer")
- }
- }
-
- var n int64
- for _, b := range p {
- n *= 10
- if b < '0' || b > '9' {
- return 0, protocolError("illegal bytes in length")
- }
- n += int64(b - '0')
- }
-
- if negate {
- n = -n
- }
- return n, nil
-}
-
-var (
- okReply interface{} = "OK"
- pongReply interface{} = "PONG"
-)
-
-func (c *conn) readReply() (interface{}, error) {
- line, err := c.readLine()
- if err != nil {
- return nil, err
- }
- if len(line) == 0 {
- return nil, protocolError("short response line")
- }
- switch line[0] {
- case '+':
- switch {
- case len(line) == 3 && line[1] == 'O' && line[2] == 'K':
- // Avoid allocation for frequent "+OK" response.
- return okReply, nil
- case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G':
- // Avoid allocation in PING command benchmarks :)
- return pongReply, nil
- default:
- return string(line[1:]), nil
- }
- case '-':
- return Error(string(line[1:])), nil
- case ':':
- return parseInt(line[1:])
- case '$':
- n, err := parseLen(line[1:])
- if n < 0 || err != nil {
- return nil, err
- }
- p := make([]byte, n)
- _, err = io.ReadFull(c.br, p)
- if err != nil {
- return nil, err
- }
- if line, err := c.readLine(); err != nil {
- return nil, err
- } else if len(line) != 0 {
- return nil, protocolError("bad bulk string format")
- }
- return p, nil
- case '*':
- n, err := parseLen(line[1:])
- if n < 0 || err != nil {
- return nil, err
- }
- r := make([]interface{}, n)
- for i := range r {
- r[i], err = c.readReply()
- if err != nil {
- return nil, err
- }
- }
- return r, nil
- }
- return nil, protocolError("unexpected response line")
-}
-
-func (c *conn) Send(cmd string, args ...interface{}) error {
- c.mu.Lock()
- c.pending += 1
- c.mu.Unlock()
- if c.writeTimeout != 0 {
- c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
- }
- if err := c.writeCommand(cmd, args); err != nil {
- return c.fatal(err)
- }
- return nil
-}
-
-func (c *conn) Flush() error {
- if c.writeTimeout != 0 {
- c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
- }
- if err := c.bw.Flush(); err != nil {
- return c.fatal(err)
- }
- return nil
-}
-
-func (c *conn) Receive() (reply interface{}, err error) {
- if c.readTimeout != 0 {
- c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
- }
- if reply, err = c.readReply(); err != nil {
- return nil, c.fatal(err)
- }
- // When using pub/sub, the number of receives can be greater than the
- // number of sends. To enable normal use of the connection after
- // unsubscribing from all channels, we do not decrement pending to a
- // negative value.
- //
- // The pending field is decremented after the reply is read to handle the
- // case where Receive is called before Send.
- c.mu.Lock()
- if c.pending > 0 {
- c.pending -= 1
- }
- c.mu.Unlock()
- if err, ok := reply.(Error); ok {
- return nil, err
- }
- return
-}
-
-func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
- c.mu.Lock()
- pending := c.pending
- c.pending = 0
- c.mu.Unlock()
-
- if cmd == "" && pending == 0 {
- return nil, nil
- }
-
- if c.writeTimeout != 0 {
- c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
- }
-
- if cmd != "" {
- if err := c.writeCommand(cmd, args); err != nil {
- return nil, c.fatal(err)
- }
- }
-
- if err := c.bw.Flush(); err != nil {
- return nil, c.fatal(err)
- }
-
- if c.readTimeout != 0 {
- c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
- }
-
- if cmd == "" {
- reply := make([]interface{}, pending)
- for i := range reply {
- r, e := c.readReply()
- if e != nil {
- return nil, c.fatal(e)
- }
- reply[i] = r
- }
- return reply, nil
- }
-
- var err error
- var reply interface{}
- for i := 0; i <= pending; i++ {
- var e error
- if reply, e = c.readReply(); e != nil {
- return nil, c.fatal(e)
- }
- if e, ok := reply.(Error); ok && err == nil {
- err = e
- }
- }
- return reply, err
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/doc.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/doc.go
deleted file mode 100644
index 1ae6f0cc2..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/doc.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis is a client for the Redis database.
-//
-// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
-// documentation about this package.
-//
-// Connections
-//
-// The Conn interface is the primary interface for working with Redis.
-// Applications create connections by calling the Dial, DialWithTimeout or
-// NewConn functions. In the future, functions will be added for creating
-// sharded and other types of connections.
-//
-// The application must call the connection Close method when the application
-// is done with the connection.
-//
-// Executing Commands
-//
-// The Conn interface has a generic method for executing Redis commands:
-//
-// Do(commandName string, args ...interface{}) (reply interface{}, err error)
-//
-// The Redis command reference (http://redis.io/commands) lists the available
-// commands. An example of using the Redis APPEND command is:
-//
-// n, err := conn.Do("APPEND", "key", "value")
-//
-// The Do method converts command arguments to binary strings for transmission
-// to the server as follows:
-//
-// Go Type Conversion
-// []byte Sent as is
-// string Sent as is
-// int, int64 strconv.FormatInt(v)
-// float64 strconv.FormatFloat(v, 'g', -1, 64)
-// bool true -> "1", false -> "0"
-// nil ""
-// all other types fmt.Print(v)
-//
-// Redis command reply types are represented using the following Go types:
-//
-// Redis type Go type
-// error redis.Error
-// integer int64
-// simple string string
-// bulk string []byte or nil if value not present.
-// array []interface{} or nil if value not present.
-//
-// Use type assertions or the reply helper functions to convert from
-// interface{} to the specific Go type for the command result.
-//
-// Pipelining
-//
-// Connections support pipelining using the Send, Flush and Receive methods.
-//
-// Send(commandName string, args ...interface{}) error
-// Flush() error
-// Receive() (reply interface{}, err error)
-//
-// Send writes the command to the connection's output buffer. Flush flushes the
-// connection's output buffer to the server. Receive reads a single reply from
-// the server. The following example shows a simple pipeline.
-//
-// c.Send("SET", "foo", "bar")
-// c.Send("GET", "foo")
-// c.Flush()
-// c.Receive() // reply from SET
-// v, err = c.Receive() // reply from GET
-//
-// The Do method combines the functionality of the Send, Flush and Receive
-// methods. The Do method starts by writing the command and flushing the output
-// buffer. Next, the Do method receives all pending replies including the reply
-// for the command just sent by Do. If any of the received replies is an error,
-// then Do returns the error. If there are no errors, then Do returns the last
-// reply. If the command argument to the Do method is "", then the Do method
-// will flush the output buffer and receive pending replies without sending a
-// command.
-//
-// Use the Send and Do methods to implement pipelined transactions.
-//
-// c.Send("MULTI")
-// c.Send("INCR", "foo")
-// c.Send("INCR", "bar")
-// r, err := c.Do("EXEC")
-// fmt.Println(r) // prints [1, 1]
-//
-// Concurrency
-//
-// Connections do not support concurrent calls to the write methods (Send,
-// Flush) or concurrent calls to the read method (Receive). Connections do
-// allow a concurrent reader and writer.
-//
-// Because the Do method combines the functionality of Send, Flush and Receive,
-// the Do method cannot be called concurrently with the other methods.
-//
-// For full concurrent access to Redis, use the thread-safe Pool to get and
-// release connections from within a goroutine.
-//
-// Publish and Subscribe
-//
-// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
-//
-// c.Send("SUBSCRIBE", "example")
-// c.Flush()
-// for {
-// reply, err := c.Receive()
-// if err != nil {
-// return err
-// }
-// // process pushed message
-// }
-//
-// The PubSubConn type wraps a Conn with convenience methods for implementing
-// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
-// send and flush a subscription management command. The receive method
-// converts a pushed message to convenient types for use in a type switch.
-//
-// psc := redis.PubSubConn{c}
-// psc.Subscribe("example")
-// for {
-// switch v := psc.Receive().(type) {
-// case redis.Message:
-// fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
-// case redis.Subscription:
-// fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
-// case error:
-// return v
-// }
-// }
-//
-// Reply Helpers
-//
-// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
-// to a value of a specific type. To allow convenient wrapping of calls to the
-// connection Do and Receive methods, the functions take a second argument of
-// type error. If the error is non-nil, then the helper function returns the
-// error. If the error is nil, the function converts the reply to the specified
-// type:
-//
-// exists, err := redis.Bool(c.Do("EXISTS", "foo"))
-// if err != nil {
-// // handle error return from c.Do or type conversion error.
-// }
-//
-// The Scan function converts elements of a array reply to Go types:
-//
-// var value1 int
-// var value2 string
-// reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
-// if err != nil {
-// // handle error
-// }
-// if _, err := redis.Scan(reply, &value1, &value2); err != nil {
-// // handle error
-// }
-package redis
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/log.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/log.go
deleted file mode 100644
index 129b86d67..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/log.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "bytes"
- "fmt"
- "log"
-)
-
-// NewLoggingConn returns a logging wrapper around a connection.
-func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
- if prefix != "" {
- prefix = prefix + "."
- }
- return &loggingConn{conn, logger, prefix}
-}
-
-type loggingConn struct {
- Conn
- logger *log.Logger
- prefix string
-}
-
-func (c *loggingConn) Close() error {
- err := c.Conn.Close()
- var buf bytes.Buffer
- fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
- c.logger.Output(2, buf.String())
- return err
-}
-
-func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
- const chop = 32
- switch v := v.(type) {
- case []byte:
- if len(v) > chop {
- fmt.Fprintf(buf, "%q...", v[:chop])
- } else {
- fmt.Fprintf(buf, "%q", v)
- }
- case string:
- if len(v) > chop {
- fmt.Fprintf(buf, "%q...", v[:chop])
- } else {
- fmt.Fprintf(buf, "%q", v)
- }
- case []interface{}:
- if len(v) == 0 {
- buf.WriteString("[]")
- } else {
- sep := "["
- fin := "]"
- if len(v) > chop {
- v = v[:chop]
- fin = "...]"
- }
- for _, vv := range v {
- buf.WriteString(sep)
- c.printValue(buf, vv)
- sep = ", "
- }
- buf.WriteString(fin)
- }
- default:
- fmt.Fprint(buf, v)
- }
-}
-
-func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
- var buf bytes.Buffer
- fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
- if method != "Receive" {
- buf.WriteString(commandName)
- for _, arg := range args {
- buf.WriteString(", ")
- c.printValue(&buf, arg)
- }
- }
- buf.WriteString(") -> (")
- if method != "Send" {
- c.printValue(&buf, reply)
- buf.WriteString(", ")
- }
- fmt.Fprintf(&buf, "%v)", err)
- c.logger.Output(3, buf.String())
-}
-
-func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
- reply, err := c.Conn.Do(commandName, args...)
- c.print("Do", commandName, args, reply, err)
- return reply, err
-}
-
-func (c *loggingConn) Send(commandName string, args ...interface{}) error {
- err := c.Conn.Send(commandName, args...)
- c.print("Send", commandName, args, nil, err)
- return err
-}
-
-func (c *loggingConn) Receive() (interface{}, error) {
- reply, err := c.Conn.Receive()
- c.print("Receive", "", nil, reply, err)
- return reply, err
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool.go
deleted file mode 100644
index d66ef84b6..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool.go
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "bytes"
- "container/list"
- "crypto/rand"
- "crypto/sha1"
- "errors"
- "io"
- "strconv"
- "sync"
- "time"
-
- "github.com/garyburd/redigo/internal"
-)
-
-var nowFunc = time.Now // for testing
-
-// ErrPoolExhausted is returned from a pool connection method (Do, Send,
-// Receive, Flush, Err) when the maximum number of database connections in the
-// pool has been reached.
-var ErrPoolExhausted = errors.New("redigo: connection pool exhausted")
-
-var (
- errPoolClosed = errors.New("redigo: connection pool closed")
- errConnClosed = errors.New("redigo: connection closed")
-)
-
-// Pool maintains a pool of connections. The application calls the Get method
-// to get a connection from the pool and the connection's Close method to
-// return the connection's resources to the pool.
-//
-// The following example shows how to use a pool in a web application. The
-// application creates a pool at application startup and makes it available to
-// request handlers using a global variable.
-//
-// func newPool(server, password string) *redis.Pool {
-// return &redis.Pool{
-// MaxIdle: 3,
-// IdleTimeout: 240 * time.Second,
-// Dial: func () (redis.Conn, error) {
-// c, err := redis.Dial("tcp", server)
-// if err != nil {
-// return nil, err
-// }
-// if _, err := c.Do("AUTH", password); err != nil {
-// c.Close()
-// return nil, err
-// }
-// return c, err
-// },
-// TestOnBorrow: func(c redis.Conn, t time.Time) error {
-// _, err := c.Do("PING")
-// return err
-// },
-// }
-// }
-//
-// var (
-// pool *redis.Pool
-// redisServer = flag.String("redisServer", ":6379", "")
-// redisPassword = flag.String("redisPassword", "", "")
-// )
-//
-// func main() {
-// flag.Parse()
-// pool = newPool(*redisServer, *redisPassword)
-// ...
-// }
-//
-// A request handler gets a connection from the pool and closes the connection
-// when the handler is done:
-//
-// func serveHome(w http.ResponseWriter, r *http.Request) {
-// conn := pool.Get()
-// defer conn.Close()
-// ....
-// }
-//
-type Pool struct {
-
- // Dial is an application supplied function for creating and configuring a
- // connection.
- //
- // The connection returned from Dial must not be in a special state
- // (subscribed to pubsub channel, transaction started, ...).
- Dial func() (Conn, error)
-
- // TestOnBorrow is an optional application supplied function for checking
- // the health of an idle connection before the connection is used again by
- // the application. Argument t is the time that the connection was returned
- // to the pool. If the function returns an error, then the connection is
- // closed.
- TestOnBorrow func(c Conn, t time.Time) error
-
- // Maximum number of idle connections in the pool.
- MaxIdle int
-
- // Maximum number of connections allocated by the pool at a given time.
- // When zero, there is no limit on the number of connections in the pool.
- MaxActive int
-
- // Close connections after remaining idle for this duration. If the value
- // is zero, then idle connections are not closed. Applications should set
- // the timeout to a value less than the server's timeout.
- IdleTimeout time.Duration
-
- // If Wait is true and the pool is at the MaxActive limit, then Get() waits
- // for a connection to be returned to the pool before returning.
- Wait bool
-
- // mu protects fields defined below.
- mu sync.Mutex
- cond *sync.Cond
- closed bool
- active int
-
- // Stack of idleConn with most recently used at the front.
- idle list.List
-}
-
-type idleConn struct {
- c Conn
- t time.Time
-}
-
-// NewPool creates a new pool.
-//
-// Deprecated: Initialize the Pool directory as shown in the example.
-func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
- return &Pool{Dial: newFn, MaxIdle: maxIdle}
-}
-
-// Get gets a connection. The application must close the returned connection.
-// This method always returns a valid connection so that applications can defer
-// error handling to the first use of the connection. If there is an error
-// getting an underlying connection, then the connection Err, Do, Send, Flush
-// and Receive methods return that error.
-func (p *Pool) Get() Conn {
- c, err := p.get()
- if err != nil {
- return errorConnection{err}
- }
- return &pooledConnection{p: p, c: c}
-}
-
-// ActiveCount returns the number of active connections in the pool.
-func (p *Pool) ActiveCount() int {
- p.mu.Lock()
- active := p.active
- p.mu.Unlock()
- return active
-}
-
-// Close releases the resources used by the pool.
-func (p *Pool) Close() error {
- p.mu.Lock()
- idle := p.idle
- p.idle.Init()
- p.closed = true
- p.active -= idle.Len()
- if p.cond != nil {
- p.cond.Broadcast()
- }
- p.mu.Unlock()
- for e := idle.Front(); e != nil; e = e.Next() {
- e.Value.(idleConn).c.Close()
- }
- return nil
-}
-
-// release decrements the active count and signals waiters. The caller must
-// hold p.mu during the call.
-func (p *Pool) release() {
- p.active -= 1
- if p.cond != nil {
- p.cond.Signal()
- }
-}
-
-// get prunes stale connections and returns a connection from the idle list or
-// creates a new connection.
-func (p *Pool) get() (Conn, error) {
- p.mu.Lock()
-
- // Prune stale connections.
-
- if timeout := p.IdleTimeout; timeout > 0 {
- for i, n := 0, p.idle.Len(); i < n; i++ {
- e := p.idle.Back()
- if e == nil {
- break
- }
- ic := e.Value.(idleConn)
- if ic.t.Add(timeout).After(nowFunc()) {
- break
- }
- p.idle.Remove(e)
- p.release()
- p.mu.Unlock()
- ic.c.Close()
- p.mu.Lock()
- }
- }
-
- for {
-
- // Get idle connection.
-
- for i, n := 0, p.idle.Len(); i < n; i++ {
- e := p.idle.Front()
- if e == nil {
- break
- }
- ic := e.Value.(idleConn)
- p.idle.Remove(e)
- test := p.TestOnBorrow
- p.mu.Unlock()
- if test == nil || test(ic.c, ic.t) == nil {
- return ic.c, nil
- }
- ic.c.Close()
- p.mu.Lock()
- p.release()
- }
-
- // Check for pool closed before dialing a new connection.
-
- if p.closed {
- p.mu.Unlock()
- return nil, errors.New("redigo: get on closed pool")
- }
-
- // Dial new connection if under limit.
-
- if p.MaxActive == 0 || p.active < p.MaxActive {
- dial := p.Dial
- p.active += 1
- p.mu.Unlock()
- c, err := dial()
- if err != nil {
- p.mu.Lock()
- p.release()
- p.mu.Unlock()
- c = nil
- }
- return c, err
- }
-
- if !p.Wait {
- p.mu.Unlock()
- return nil, ErrPoolExhausted
- }
-
- if p.cond == nil {
- p.cond = sync.NewCond(&p.mu)
- }
- p.cond.Wait()
- }
-}
-
-func (p *Pool) put(c Conn, forceClose bool) error {
- err := c.Err()
- p.mu.Lock()
- if !p.closed && err == nil && !forceClose {
- p.idle.PushFront(idleConn{t: nowFunc(), c: c})
- if p.idle.Len() > p.MaxIdle {
- c = p.idle.Remove(p.idle.Back()).(idleConn).c
- } else {
- c = nil
- }
- }
-
- if c == nil {
- if p.cond != nil {
- p.cond.Signal()
- }
- p.mu.Unlock()
- return nil
- }
-
- p.release()
- p.mu.Unlock()
- return c.Close()
-}
-
-type pooledConnection struct {
- p *Pool
- c Conn
- state int
-}
-
-var (
- sentinel []byte
- sentinelOnce sync.Once
-)
-
-func initSentinel() {
- p := make([]byte, 64)
- if _, err := rand.Read(p); err == nil {
- sentinel = p
- } else {
- h := sha1.New()
- io.WriteString(h, "Oops, rand failed. Use time instead.")
- io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10))
- sentinel = h.Sum(nil)
- }
-}
-
-func (pc *pooledConnection) Close() error {
- c := pc.c
- if _, ok := c.(errorConnection); ok {
- return nil
- }
- pc.c = errorConnection{errConnClosed}
-
- if pc.state&internal.MultiState != 0 {
- c.Send("DISCARD")
- pc.state &^= (internal.MultiState | internal.WatchState)
- } else if pc.state&internal.WatchState != 0 {
- c.Send("UNWATCH")
- pc.state &^= internal.WatchState
- }
- if pc.state&internal.SubscribeState != 0 {
- c.Send("UNSUBSCRIBE")
- c.Send("PUNSUBSCRIBE")
- // To detect the end of the message stream, ask the server to echo
- // a sentinel value and read until we see that value.
- sentinelOnce.Do(initSentinel)
- c.Send("ECHO", sentinel)
- c.Flush()
- for {
- p, err := c.Receive()
- if err != nil {
- break
- }
- if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
- pc.state &^= internal.SubscribeState
- break
- }
- }
- }
- c.Do("")
- pc.p.put(c, pc.state != 0)
- return nil
-}
-
-func (pc *pooledConnection) Err() error {
- return pc.c.Err()
-}
-
-func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
- ci := internal.LookupCommandInfo(commandName)
- pc.state = (pc.state | ci.Set) &^ ci.Clear
- return pc.c.Do(commandName, args...)
-}
-
-func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
- ci := internal.LookupCommandInfo(commandName)
- pc.state = (pc.state | ci.Set) &^ ci.Clear
- return pc.c.Send(commandName, args...)
-}
-
-func (pc *pooledConnection) Flush() error {
- return pc.c.Flush()
-}
-
-func (pc *pooledConnection) Receive() (reply interface{}, err error) {
- return pc.c.Receive()
-}
-
-type errorConnection struct{ err error }
-
-func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
-func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
-func (ec errorConnection) Err() error { return ec.err }
-func (ec errorConnection) Close() error { return ec.err }
-func (ec errorConnection) Flush() error { return ec.err }
-func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub.go
deleted file mode 100644
index c0ecce824..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import "errors"
-
-// Subscription represents a subscribe or unsubscribe notification.
-type Subscription struct {
-
- // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
- Kind string
-
- // The channel that was changed.
- Channel string
-
- // The current number of subscriptions for connection.
- Count int
-}
-
-// Message represents a message notification.
-type Message struct {
-
- // The originating channel.
- Channel string
-
- // The message data.
- Data []byte
-}
-
-// PMessage represents a pmessage notification.
-type PMessage struct {
-
- // The matched pattern.
- Pattern string
-
- // The originating channel.
- Channel string
-
- // The message data.
- Data []byte
-}
-
-// Pong represents a pubsub pong notification.
-type Pong struct {
- Data string
-}
-
-// PubSubConn wraps a Conn with convenience methods for subscribers.
-type PubSubConn struct {
- Conn Conn
-}
-
-// Close closes the connection.
-func (c PubSubConn) Close() error {
- return c.Conn.Close()
-}
-
-// Subscribe subscribes the connection to the specified channels.
-func (c PubSubConn) Subscribe(channel ...interface{}) error {
- c.Conn.Send("SUBSCRIBE", channel...)
- return c.Conn.Flush()
-}
-
-// PSubscribe subscribes the connection to the given patterns.
-func (c PubSubConn) PSubscribe(channel ...interface{}) error {
- c.Conn.Send("PSUBSCRIBE", channel...)
- return c.Conn.Flush()
-}
-
-// Unsubscribe unsubscribes the connection from the given channels, or from all
-// of them if none is given.
-func (c PubSubConn) Unsubscribe(channel ...interface{}) error {
- c.Conn.Send("UNSUBSCRIBE", channel...)
- return c.Conn.Flush()
-}
-
-// PUnsubscribe unsubscribes the connection from the given patterns, or from all
-// of them if none is given.
-func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
- c.Conn.Send("PUNSUBSCRIBE", channel...)
- return c.Conn.Flush()
-}
-
-// Ping sends a PING to the server with the specified data.
-func (c PubSubConn) Ping(data string) error {
- c.Conn.Send("PING", data)
- return c.Conn.Flush()
-}
-
-// Receive returns a pushed message as a Subscription, Message, PMessage, Pong
-// or error. The return value is intended to be used directly in a type switch
-// as illustrated in the PubSubConn example.
-func (c PubSubConn) Receive() interface{} {
- reply, err := Values(c.Conn.Receive())
- if err != nil {
- return err
- }
-
- var kind string
- reply, err = Scan(reply, &kind)
- if err != nil {
- return err
- }
-
- switch kind {
- case "message":
- var m Message
- if _, err := Scan(reply, &m.Channel, &m.Data); err != nil {
- return err
- }
- return m
- case "pmessage":
- var pm PMessage
- if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil {
- return err
- }
- return pm
- case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
- s := Subscription{Kind: kind}
- if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
- return err
- }
- return s
- case "pong":
- var p Pong
- if _, err := Scan(reply, &p.Data); err != nil {
- return err
- }
- return p
- }
- return errors.New("redigo: unknown pubsub notification")
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go
deleted file mode 100644
index c90a48ed4..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-// Error represents an error returned in a command reply.
-type Error string
-
-func (err Error) Error() string { return string(err) }
-
-// Conn represents a connection to a Redis server.
-type Conn interface {
- // Close closes the connection.
- Close() error
-
- // Err returns a non-nil value if the connection is broken. The returned
- // value is either the first non-nil value returned from the underlying
- // network connection or a protocol parsing error. Applications should
- // close broken connections.
- Err() error
-
- // Do sends a command to the server and returns the received reply.
- Do(commandName string, args ...interface{}) (reply interface{}, err error)
-
- // Send writes the command to the client's output buffer.
- Send(commandName string, args ...interface{}) error
-
- // Flush flushes the output buffer to the Redis server.
- Flush() error
-
- // Receive receives a single reply from the Redis server
- Receive() (reply interface{}, err error)
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply.go
deleted file mode 100644
index 57896147f..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply.go
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "errors"
- "fmt"
- "strconv"
-)
-
-// ErrNil indicates that a reply value is nil.
-var ErrNil = errors.New("redigo: nil returned")
-
-// Int is a helper that converts a command reply to an integer. If err is not
-// equal to nil, then Int returns 0, err. Otherwise, Int converts the
-// reply to an int as follows:
-//
-// Reply type Result
-// integer int(reply), nil
-// bulk string parsed reply, nil
-// nil 0, ErrNil
-// other 0, error
-func Int(reply interface{}, err error) (int, error) {
- if err != nil {
- return 0, err
- }
- switch reply := reply.(type) {
- case int64:
- x := int(reply)
- if int64(x) != reply {
- return 0, strconv.ErrRange
- }
- return x, nil
- case []byte:
- n, err := strconv.ParseInt(string(reply), 10, 0)
- return int(n), err
- case nil:
- return 0, ErrNil
- case Error:
- return 0, reply
- }
- return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
-}
-
-// Int64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-// Reply type Result
-// integer reply, nil
-// bulk string parsed reply, nil
-// nil 0, ErrNil
-// other 0, error
-func Int64(reply interface{}, err error) (int64, error) {
- if err != nil {
- return 0, err
- }
- switch reply := reply.(type) {
- case int64:
- return reply, nil
- case []byte:
- n, err := strconv.ParseInt(string(reply), 10, 64)
- return n, err
- case nil:
- return 0, ErrNil
- case Error:
- return 0, reply
- }
- return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply)
-}
-
-var errNegativeInt = errors.New("redigo: unexpected value for Uint64")
-
-// Uint64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-// Reply type Result
-// integer reply, nil
-// bulk string parsed reply, nil
-// nil 0, ErrNil
-// other 0, error
-func Uint64(reply interface{}, err error) (uint64, error) {
- if err != nil {
- return 0, err
- }
- switch reply := reply.(type) {
- case int64:
- if reply < 0 {
- return 0, errNegativeInt
- }
- return uint64(reply), nil
- case []byte:
- n, err := strconv.ParseUint(string(reply), 10, 64)
- return n, err
- case nil:
- return 0, ErrNil
- case Error:
- return 0, reply
- }
- return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply)
-}
-
-// Float64 is a helper that converts a command reply to 64 bit float. If err is
-// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts
-// the reply to an int as follows:
-//
-// Reply type Result
-// bulk string parsed reply, nil
-// nil 0, ErrNil
-// other 0, error
-func Float64(reply interface{}, err error) (float64, error) {
- if err != nil {
- return 0, err
- }
- switch reply := reply.(type) {
- case []byte:
- n, err := strconv.ParseFloat(string(reply), 64)
- return n, err
- case nil:
- return 0, ErrNil
- case Error:
- return 0, reply
- }
- return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply)
-}
-
-// String is a helper that converts a command reply to a string. If err is not
-// equal to nil, then String returns "", err. Otherwise String converts the
-// reply to a string as follows:
-//
-// Reply type Result
-// bulk string string(reply), nil
-// simple string reply, nil
-// nil "", ErrNil
-// other "", error
-func String(reply interface{}, err error) (string, error) {
- if err != nil {
- return "", err
- }
- switch reply := reply.(type) {
- case []byte:
- return string(reply), nil
- case string:
- return reply, nil
- case nil:
- return "", ErrNil
- case Error:
- return "", reply
- }
- return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
-}
-
-// Bytes is a helper that converts a command reply to a slice of bytes. If err
-// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
-// the reply to a slice of bytes as follows:
-//
-// Reply type Result
-// bulk string reply, nil
-// simple string []byte(reply), nil
-// nil nil, ErrNil
-// other nil, error
-func Bytes(reply interface{}, err error) ([]byte, error) {
- if err != nil {
- return nil, err
- }
- switch reply := reply.(type) {
- case []byte:
- return reply, nil
- case string:
- return []byte(reply), nil
- case nil:
- return nil, ErrNil
- case Error:
- return nil, reply
- }
- return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
-}
-
-// Bool is a helper that converts a command reply to a boolean. If err is not
-// equal to nil, then Bool returns false, err. Otherwise Bool converts the
-// reply to boolean as follows:
-//
-// Reply type Result
-// integer value != 0, nil
-// bulk string strconv.ParseBool(reply)
-// nil false, ErrNil
-// other false, error
-func Bool(reply interface{}, err error) (bool, error) {
- if err != nil {
- return false, err
- }
- switch reply := reply.(type) {
- case int64:
- return reply != 0, nil
- case []byte:
- return strconv.ParseBool(string(reply))
- case nil:
- return false, ErrNil
- case Error:
- return false, reply
- }
- return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
-}
-
-// MultiBulk is a helper that converts an array command reply to a []interface{}.
-//
-// Deprecated: Use Values instead.
-func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
-
-// Values is a helper that converts an array command reply to a []interface{}.
-// If err is not equal to nil, then Values returns nil, err. Otherwise, Values
-// converts the reply as follows:
-//
-// Reply type Result
-// array reply, nil
-// nil nil, ErrNil
-// other nil, error
-func Values(reply interface{}, err error) ([]interface{}, error) {
- if err != nil {
- return nil, err
- }
- switch reply := reply.(type) {
- case []interface{}:
- return reply, nil
- case nil:
- return nil, ErrNil
- case Error:
- return nil, reply
- }
- return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
-}
-
-// Strings is a helper that converts an array command reply to a []string. If
-// err is not equal to nil, then Strings returns nil, err. Nil array items are
-// converted to "" in the output slice. Strings returns an error if an array
-// item is not a bulk string or nil.
-func Strings(reply interface{}, err error) ([]string, error) {
- if err != nil {
- return nil, err
- }
- switch reply := reply.(type) {
- case []interface{}:
- result := make([]string, len(reply))
- for i := range reply {
- if reply[i] == nil {
- continue
- }
- p, ok := reply[i].([]byte)
- if !ok {
- return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i])
- }
- result[i] = string(p)
- }
- return result, nil
- case nil:
- return nil, ErrNil
- case Error:
- return nil, reply
- }
- return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply)
-}
-
-// ByteSlices is a helper that converts an array command reply to a [][]byte.
-// If err is not equal to nil, then ByteSlices returns nil, err. Nil array
-// items are stay nil. ByteSlices returns an error if an array item is not a
-// bulk string or nil.
-func ByteSlices(reply interface{}, err error) ([][]byte, error) {
- if err != nil {
- return nil, err
- }
- switch reply := reply.(type) {
- case []interface{}:
- result := make([][]byte, len(reply))
- for i := range reply {
- if reply[i] == nil {
- continue
- }
- p, ok := reply[i].([]byte)
- if !ok {
- return nil, fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", reply[i])
- }
- result[i] = p
- }
- return result, nil
- case nil:
- return nil, ErrNil
- case Error:
- return nil, reply
- }
- return nil, fmt.Errorf("redigo: unexpected type for ByteSlices, got type %T", reply)
-}
-
-// Ints is a helper that converts an array command reply to a []int. If
-// err is not equal to nil, then Ints returns nil, err.
-func Ints(reply interface{}, err error) ([]int, error) {
- var ints []int
- values, err := Values(reply, err)
- if err != nil {
- return ints, err
- }
- if err := ScanSlice(values, &ints); err != nil {
- return ints, err
- }
- return ints, nil
-}
-
-// StringMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format.
-// Requires an even number of values in result.
-func StringMap(result interface{}, err error) (map[string]string, error) {
- values, err := Values(result, err)
- if err != nil {
- return nil, err
- }
- if len(values)%2 != 0 {
- return nil, errors.New("redigo: StringMap expects even number of values result")
- }
- m := make(map[string]string, len(values)/2)
- for i := 0; i < len(values); i += 2 {
- key, okKey := values[i].([]byte)
- value, okValue := values[i+1].([]byte)
- if !okKey || !okValue {
- return nil, errors.New("redigo: ScanMap key not a bulk string value")
- }
- m[string(key)] = string(value)
- }
- return m, nil
-}
-
-// IntMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func IntMap(result interface{}, err error) (map[string]int, error) {
- values, err := Values(result, err)
- if err != nil {
- return nil, err
- }
- if len(values)%2 != 0 {
- return nil, errors.New("redigo: IntMap expects even number of values result")
- }
- m := make(map[string]int, len(values)/2)
- for i := 0; i < len(values); i += 2 {
- key, ok := values[i].([]byte)
- if !ok {
- return nil, errors.New("redigo: ScanMap key not a bulk string value")
- }
- value, err := Int(values[i+1], nil)
- if err != nil {
- return nil, err
- }
- m[string(key)] = value
- }
- return m, nil
-}
-
-// Int64Map is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int64. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func Int64Map(result interface{}, err error) (map[string]int64, error) {
- values, err := Values(result, err)
- if err != nil {
- return nil, err
- }
- if len(values)%2 != 0 {
- return nil, errors.New("redigo: Int64Map expects even number of values result")
- }
- m := make(map[string]int64, len(values)/2)
- for i := 0; i < len(values); i += 2 {
- key, ok := values[i].([]byte)
- if !ok {
- return nil, errors.New("redigo: ScanMap key not a bulk string value")
- }
- value, err := Int64(values[i+1], nil)
- if err != nil {
- return nil, err
- }
- m[string(key)] = value
- }
- return m, nil
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan.go
deleted file mode 100644
index 962e94bcc..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan.go
+++ /dev/null
@@ -1,555 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "sync"
-)
-
-func ensureLen(d reflect.Value, n int) {
- if n > d.Cap() {
- d.Set(reflect.MakeSlice(d.Type(), n, n))
- } else {
- d.SetLen(n)
- }
-}
-
-func cannotConvert(d reflect.Value, s interface{}) error {
- var sname string
- switch s.(type) {
- case string:
- sname = "Redis simple string"
- case Error:
- sname = "Redis error"
- case int64:
- sname = "Redis integer"
- case []byte:
- sname = "Redis bulk string"
- case []interface{}:
- sname = "Redis array"
- default:
- sname = reflect.TypeOf(s).String()
- }
- return fmt.Errorf("cannot convert from %s to %s", sname, d.Type())
-}
-
-func convertAssignBulkString(d reflect.Value, s []byte) (err error) {
- switch d.Type().Kind() {
- case reflect.Float32, reflect.Float64:
- var x float64
- x, err = strconv.ParseFloat(string(s), d.Type().Bits())
- d.SetFloat(x)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- var x int64
- x, err = strconv.ParseInt(string(s), 10, d.Type().Bits())
- d.SetInt(x)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- var x uint64
- x, err = strconv.ParseUint(string(s), 10, d.Type().Bits())
- d.SetUint(x)
- case reflect.Bool:
- var x bool
- x, err = strconv.ParseBool(string(s))
- d.SetBool(x)
- case reflect.String:
- d.SetString(string(s))
- case reflect.Slice:
- if d.Type().Elem().Kind() != reflect.Uint8 {
- err = cannotConvert(d, s)
- } else {
- d.SetBytes(s)
- }
- default:
- err = cannotConvert(d, s)
- }
- return
-}
-
-func convertAssignInt(d reflect.Value, s int64) (err error) {
- switch d.Type().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- d.SetInt(s)
- if d.Int() != s {
- err = strconv.ErrRange
- d.SetInt(0)
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- if s < 0 {
- err = strconv.ErrRange
- } else {
- x := uint64(s)
- d.SetUint(x)
- if d.Uint() != x {
- err = strconv.ErrRange
- d.SetUint(0)
- }
- }
- case reflect.Bool:
- d.SetBool(s != 0)
- default:
- err = cannotConvert(d, s)
- }
- return
-}
-
-func convertAssignValue(d reflect.Value, s interface{}) (err error) {
- switch s := s.(type) {
- case []byte:
- err = convertAssignBulkString(d, s)
- case int64:
- err = convertAssignInt(d, s)
- default:
- err = cannotConvert(d, s)
- }
- return err
-}
-
-func convertAssignArray(d reflect.Value, s []interface{}) error {
- if d.Type().Kind() != reflect.Slice {
- return cannotConvert(d, s)
- }
- ensureLen(d, len(s))
- for i := 0; i < len(s); i++ {
- if err := convertAssignValue(d.Index(i), s[i]); err != nil {
- return err
- }
- }
- return nil
-}
-
-func convertAssign(d interface{}, s interface{}) (err error) {
- // Handle the most common destination types using type switches and
- // fall back to reflection for all other types.
- switch s := s.(type) {
- case nil:
- // ingore
- case []byte:
- switch d := d.(type) {
- case *string:
- *d = string(s)
- case *int:
- *d, err = strconv.Atoi(string(s))
- case *bool:
- *d, err = strconv.ParseBool(string(s))
- case *[]byte:
- *d = s
- case *interface{}:
- *d = s
- case nil:
- // skip value
- default:
- if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
- err = cannotConvert(d, s)
- } else {
- err = convertAssignBulkString(d.Elem(), s)
- }
- }
- case int64:
- switch d := d.(type) {
- case *int:
- x := int(s)
- if int64(x) != s {
- err = strconv.ErrRange
- x = 0
- }
- *d = x
- case *bool:
- *d = s != 0
- case *interface{}:
- *d = s
- case nil:
- // skip value
- default:
- if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
- err = cannotConvert(d, s)
- } else {
- err = convertAssignInt(d.Elem(), s)
- }
- }
- case string:
- switch d := d.(type) {
- case *string:
- *d = string(s)
- default:
- err = cannotConvert(reflect.ValueOf(d), s)
- }
- case []interface{}:
- switch d := d.(type) {
- case *[]interface{}:
- *d = s
- case *interface{}:
- *d = s
- case nil:
- // skip value
- default:
- if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
- err = cannotConvert(d, s)
- } else {
- err = convertAssignArray(d.Elem(), s)
- }
- }
- case Error:
- err = s
- default:
- err = cannotConvert(reflect.ValueOf(d), s)
- }
- return
-}
-
-// Scan copies from src to the values pointed at by dest.
-//
-// The values pointed at by dest must be an integer, float, boolean, string,
-// []byte, interface{} or slices of these types. Scan uses the standard strconv
-// package to convert bulk strings to numeric and boolean types.
-//
-// If a dest value is nil, then the corresponding src value is skipped.
-//
-// If a src element is nil, then the corresponding dest value is not modified.
-//
-// To enable easy use of Scan in a loop, Scan returns the slice of src
-// following the copied values.
-func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
- if len(src) < len(dest) {
- return nil, errors.New("redigo.Scan: array short")
- }
- var err error
- for i, d := range dest {
- err = convertAssign(d, src[i])
- if err != nil {
- err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err)
- break
- }
- }
- return src[len(dest):], err
-}
-
-type fieldSpec struct {
- name string
- index []int
- omitEmpty bool
-}
-
-type structSpec struct {
- m map[string]*fieldSpec
- l []*fieldSpec
-}
-
-func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
- return ss.m[string(name)]
-}
-
-func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
- for i := 0; i < t.NumField(); i++ {
- f := t.Field(i)
- switch {
- case f.PkgPath != "" && !f.Anonymous:
- // Ignore unexported fields.
- case f.Anonymous:
- // TODO: Handle pointers. Requires change to decoder and
- // protection against infinite recursion.
- if f.Type.Kind() == reflect.Struct {
- compileStructSpec(f.Type, depth, append(index, i), ss)
- }
- default:
- fs := &fieldSpec{name: f.Name}
- tag := f.Tag.Get("redis")
- p := strings.Split(tag, ",")
- if len(p) > 0 {
- if p[0] == "-" {
- continue
- }
- if len(p[0]) > 0 {
- fs.name = p[0]
- }
- for _, s := range p[1:] {
- switch s {
- case "omitempty":
- fs.omitEmpty = true
- default:
- panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name()))
- }
- }
- }
- d, found := depth[fs.name]
- if !found {
- d = 1 << 30
- }
- switch {
- case len(index) == d:
- // At same depth, remove from result.
- delete(ss.m, fs.name)
- j := 0
- for i := 0; i < len(ss.l); i++ {
- if fs.name != ss.l[i].name {
- ss.l[j] = ss.l[i]
- j += 1
- }
- }
- ss.l = ss.l[:j]
- case len(index) < d:
- fs.index = make([]int, len(index)+1)
- copy(fs.index, index)
- fs.index[len(index)] = i
- depth[fs.name] = len(index)
- ss.m[fs.name] = fs
- ss.l = append(ss.l, fs)
- }
- }
- }
-}
-
-var (
- structSpecMutex sync.RWMutex
- structSpecCache = make(map[reflect.Type]*structSpec)
- defaultFieldSpec = &fieldSpec{}
-)
-
-func structSpecForType(t reflect.Type) *structSpec {
-
- structSpecMutex.RLock()
- ss, found := structSpecCache[t]
- structSpecMutex.RUnlock()
- if found {
- return ss
- }
-
- structSpecMutex.Lock()
- defer structSpecMutex.Unlock()
- ss, found = structSpecCache[t]
- if found {
- return ss
- }
-
- ss = &structSpec{m: make(map[string]*fieldSpec)}
- compileStructSpec(t, make(map[string]int), nil, ss)
- structSpecCache[t] = ss
- return ss
-}
-
-var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct")
-
-// ScanStruct scans alternating names and values from src to a struct. The
-// HGETALL and CONFIG GET commands return replies in this format.
-//
-// ScanStruct uses exported field names to match values in the response. Use
-// 'redis' field tag to override the name:
-//
-// Field int `redis:"myName"`
-//
-// Fields with the tag redis:"-" are ignored.
-//
-// Integer, float, boolean, string and []byte fields are supported. Scan uses the
-// standard strconv package to convert bulk string values to numeric and
-// boolean types.
-//
-// If a src element is nil, then the corresponding field is not modified.
-func ScanStruct(src []interface{}, dest interface{}) error {
- d := reflect.ValueOf(dest)
- if d.Kind() != reflect.Ptr || d.IsNil() {
- return errScanStructValue
- }
- d = d.Elem()
- if d.Kind() != reflect.Struct {
- return errScanStructValue
- }
- ss := structSpecForType(d.Type())
-
- if len(src)%2 != 0 {
- return errors.New("redigo.ScanStruct: number of values not a multiple of 2")
- }
-
- for i := 0; i < len(src); i += 2 {
- s := src[i+1]
- if s == nil {
- continue
- }
- name, ok := src[i].([]byte)
- if !ok {
- return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i)
- }
- fs := ss.fieldSpec(name)
- if fs == nil {
- continue
- }
- if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
- return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err)
- }
- }
- return nil
-}
-
-var (
- errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct")
-)
-
-// ScanSlice scans src to the slice pointed to by dest. The elements the dest
-// slice must be integer, float, boolean, string, struct or pointer to struct
-// values.
-//
-// Struct fields must be integer, float, boolean or string values. All struct
-// fields are used unless a subset is specified using fieldNames.
-func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
- d := reflect.ValueOf(dest)
- if d.Kind() != reflect.Ptr || d.IsNil() {
- return errScanSliceValue
- }
- d = d.Elem()
- if d.Kind() != reflect.Slice {
- return errScanSliceValue
- }
-
- isPtr := false
- t := d.Type().Elem()
- if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
- isPtr = true
- t = t.Elem()
- }
-
- if t.Kind() != reflect.Struct {
- ensureLen(d, len(src))
- for i, s := range src {
- if s == nil {
- continue
- }
- if err := convertAssignValue(d.Index(i), s); err != nil {
- return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err)
- }
- }
- return nil
- }
-
- ss := structSpecForType(t)
- fss := ss.l
- if len(fieldNames) > 0 {
- fss = make([]*fieldSpec, len(fieldNames))
- for i, name := range fieldNames {
- fss[i] = ss.m[name]
- if fss[i] == nil {
- return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name)
- }
- }
- }
-
- if len(fss) == 0 {
- return errors.New("redigo.ScanSlice: no struct fields")
- }
-
- n := len(src) / len(fss)
- if n*len(fss) != len(src) {
- return errors.New("redigo.ScanSlice: length not a multiple of struct field count")
- }
-
- ensureLen(d, n)
- for i := 0; i < n; i++ {
- d := d.Index(i)
- if isPtr {
- if d.IsNil() {
- d.Set(reflect.New(t))
- }
- d = d.Elem()
- }
- for j, fs := range fss {
- s := src[i*len(fss)+j]
- if s == nil {
- continue
- }
- if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
- return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err)
- }
- }
- }
- return nil
-}
-
-// Args is a helper for constructing command arguments from structured values.
-type Args []interface{}
-
-// Add returns the result of appending value to args.
-func (args Args) Add(value ...interface{}) Args {
- return append(args, value...)
-}
-
-// AddFlat returns the result of appending the flattened value of v to args.
-//
-// Maps are flattened by appending the alternating keys and map values to args.
-//
-// Slices are flattened by appending the slice elements to args.
-//
-// Structs are flattened by appending the alternating names and values of
-// exported fields to args. If v is a nil struct pointer, then nothing is
-// appended. The 'redis' field tag overrides struct field names. See ScanStruct
-// for more information on the use of the 'redis' field tag.
-//
-// Other types are appended to args as is.
-func (args Args) AddFlat(v interface{}) Args {
- rv := reflect.ValueOf(v)
- switch rv.Kind() {
- case reflect.Struct:
- args = flattenStruct(args, rv)
- case reflect.Slice:
- for i := 0; i < rv.Len(); i++ {
- args = append(args, rv.Index(i).Interface())
- }
- case reflect.Map:
- for _, k := range rv.MapKeys() {
- args = append(args, k.Interface(), rv.MapIndex(k).Interface())
- }
- case reflect.Ptr:
- if rv.Type().Elem().Kind() == reflect.Struct {
- if !rv.IsNil() {
- args = flattenStruct(args, rv.Elem())
- }
- } else {
- args = append(args, v)
- }
- default:
- args = append(args, v)
- }
- return args
-}
-
-func flattenStruct(args Args, v reflect.Value) Args {
- ss := structSpecForType(v.Type())
- for _, fs := range ss.l {
- fv := v.FieldByIndex(fs.index)
- if fs.omitEmpty {
- var empty = false
- switch fv.Kind() {
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- empty = fv.Len() == 0
- case reflect.Bool:
- empty = !fv.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- empty = fv.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- empty = fv.Uint() == 0
- case reflect.Float32, reflect.Float64:
- empty = fv.Float() == 0
- case reflect.Interface, reflect.Ptr:
- empty = fv.IsNil()
- }
- if empty {
- continue
- }
- }
- args = append(args, fs.name, fv.Interface())
- }
- return args
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script.go
deleted file mode 100644
index 78605a90a..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// 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 redis
-
-import (
- "crypto/sha1"
- "encoding/hex"
- "io"
- "strings"
-)
-
-// Script encapsulates the source, hash and key count for a Lua script. See
-// http://redis.io/commands/eval for information on scripts in Redis.
-type Script struct {
- keyCount int
- src string
- hash string
-}
-
-// NewScript returns a new script object. If keyCount is greater than or equal
-// to zero, then the count is automatically inserted in the EVAL command
-// argument list. If keyCount is less than zero, then the application supplies
-// the count as the first value in the keysAndArgs argument to the Do, Send and
-// SendHash methods.
-func NewScript(keyCount int, src string) *Script {
- h := sha1.New()
- io.WriteString(h, src)
- return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))}
-}
-
-func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
- var args []interface{}
- if s.keyCount < 0 {
- args = make([]interface{}, 1+len(keysAndArgs))
- args[0] = spec
- copy(args[1:], keysAndArgs)
- } else {
- args = make([]interface{}, 2+len(keysAndArgs))
- args[0] = spec
- args[1] = s.keyCount
- copy(args[2:], keysAndArgs)
- }
- return args
-}
-
-// Do evaluates the script. Under the covers, Do optimistically evaluates the
-// script using the EVALSHA command. If the command fails because the script is
-// not loaded, then Do evaluates the script using the EVAL command (thus
-// causing the script to load).
-func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) {
- v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...)
- if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
- v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...)
- }
- return v, err
-}
-
-// SendHash evaluates the script without waiting for the reply. The script is
-// evaluated with the EVALSHA command. The application must ensure that the
-// script is loaded by a previous call to Send, Do or Load methods.
-func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error {
- return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...)
-}
-
-// Send evaluates the script without waiting for the reply.
-func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error {
- return c.Send("EVAL", s.args(s.src, keysAndArgs)...)
-}
-
-// Load loads the script without evaluating it.
-func (s *Script) Load(c Conn) error {
- _, err := c.Do("SCRIPT", "LOAD", s.src)
- return err
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/.gitignore b/Godeps/_workspace/src/github.com/go-gorp/gorp/.gitignore
deleted file mode 100644
index 8a06adea5..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-_test
-_testmain.go
-_obj
-*~
-*.6
-6.out
-gorptest.bin
-tmp
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/.travis.yml b/Godeps/_workspace/src/github.com/go-gorp/gorp/.travis.yml
deleted file mode 100644
index ce4602884..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/.travis.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-language: go
-go:
-- 1.3
-- 1.4
-- tip
-
-services:
-- mysql
-- postgres
-- sqlite3
-
-env:
- global:
- - secure: RriLxF6+2yMl67hdVv8ImXlu0h62mhcpqjaOgYNU+IEbUQ7hx96CKY6gkpYubW3BgApvF5RH6j3+HKvh2kGp0XhDOYOQCODfBSaSipZ5Aa5RKjsEYLtuVIobvJ80awR9hUeql69+WXs0/s72WThG0qTbOUY4pqHWfteeY235hWM=
-
-before_script:
-- mysql -e "CREATE DATABASE gorptest;"
-- mysql -u root -e "GRANT ALL ON gorptest.* TO gorptest@localhost IDENTIFIED BY 'gorptest'"
-- psql -c "CREATE DATABASE gorptest;" -U postgres
-- psql -c "CREATE USER "gorptest" WITH SUPERUSER PASSWORD 'gorptest';" -U postgres
-- go get github.com/lib/pq
-- go get github.com/mattn/go-sqlite3
-- go get github.com/ziutek/mymysql/godrv
-- go get github.com/go-sql-driver/mysql
-- go get golang.org/x/tools/cmd/cover
-- go get github.com/mattn/goveralls
-
-script: ./test_all.sh
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/LICENSE b/Godeps/_workspace/src/github.com/go-gorp/gorp/LICENSE
deleted file mode 100644
index b661111d0..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2012 James Cooper <james@bitmechanic.com>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md b/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md
deleted file mode 100644
index 8b9277805..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md
+++ /dev/null
@@ -1,745 +0,0 @@
-# Go Relational Persistence
-
-[![build status](https://img.shields.io/travis/go-gorp/gorp.svg)](http://travis-ci.org/go-gorp/gorp)
-[![code coverage](https://img.shields.io/coveralls/go-gorp/gorp.svg)](https://coveralls.io/r/go-gorp/gorp)
-[![issues](https://img.shields.io/github/issues/go-gorp/gorp.svg)](https://github.com/go-gorp/gorp/issues)
-[![godoc v1](https://img.shields.io/badge/godoc-v1-375EAB.svg)](https://godoc.org/gopkg.in/gorp.v1)
-[![godoc bleeding edge](https://img.shields.io/badge/godoc-bleeding--edge-375EAB.svg)](https://godoc.org/github.com/go-gorp/gorp)
-
-### Update 2015-07-01 Cleanup & feature freeze ([#270](https://github.com/go-gorp/gorp/issues/270))
-
-We are currently cleaning up the backlog of issues and PR's. When this is done the codebase will be split into separate files and there will be breaking changes to the API's. We're also adding better tests and documentation. As a result of these changes the `master` branch will be unstable. Please use `gopkg.in/gorp.v1`. When the cleanup and changes are done, we will release `v2.0`.
-
-At this time we won't accept new feature-related pull-requests because of changes to the codebase. Please create an issue for your feature and wait until `v2.0` has been released.
-
-For more information, please read [#270](https://github.com/go-gorp/gorp/issues/270).
-
-## Introduction
-
-I hesitate to call gorp an ORM. Go doesn't really have objects, at least not in the classic Smalltalk/Java sense. There goes the "O". gorp doesn't know anything about the relationships between your structs (at least not yet). So the "R" is questionable too (but I use it in the name because, well, it seemed more clever).
-
-The "M" is alive and well. Given some Go structs and a database, gorp should remove a fair amount of boilerplate busy-work from your code.
-
-I hope that gorp saves you time, minimizes the drudgery of getting data in and out of your database, and helps your code focus on algorithms, not infrastructure.
-
-* Bind struct fields to table columns via API or tag
-* Support for embedded structs
-* Support for transactions
-* Forward engineer db schema from structs (great for unit tests)
-* Pre/post insert/update/delete hooks
-* Automatically generate insert/update/delete statements for a struct
-* Automatic binding of auto increment PKs back to struct after insert
-* Delete by primary key(s)
-* Select by primary key(s)
-* Optional trace sql logging
-* Bind arbitrary SQL queries to a struct
-* Bind slice to SELECT query results without type assertions
-* Use positional or named bind parameters in custom SELECT queries
-* Optional optimistic locking using a version column (for update/deletes)
-
-## Installation
-
- # install the library:
- go get gopkg.in/gorp.v1
-
- // use in your .go code:
- import (
- "gopkg.in/gorp.v1"
- )
-
-## Versioning
-
-This project provides a stable release (v1.x tags) and a bleeding edge codebase (master).
-
-`gopkg.in/gorp.v1` points to the latest v1.x tag. The API's for v1 are stable and shouldn't change. Development takes place at the master branch. Althought the code in master should always compile and test successfully, it might break API's. We aim to maintain backwards compatibility, but API's and behaviour might be changed to fix a bug. Also note that API's that are new in the master branch can change until released as v2.
-
-If you want to use bleeding edge, use `github.com/go-gorp/gorp` as import path.
-
-## API Documentation
-
-Full godoc output from the latest v1 release is available here:
-
-https://godoc.org/gopkg.in/gorp.v1
-
-For the latest code in master:
-
-https://godoc.org/github.com/go-gorp/gorp
-
-## Supported Go versions
-
-This package is compatible with the last 2 major versions of Go, at this time `1.3` and `1.4`.
-
-Any earlier versions are only supported on a best effort basis and can be dropped any time.
-Go has a great compatibility promise. Upgrading your program to a newer version of Go should never really be a problem.
-
-## Quickstart
-
-```go
-package main
-
-import (
- "database/sql"
- "gopkg.in/gorp.v1"
- _ "github.com/mattn/go-sqlite3"
- "log"
- "time"
-)
-
-func main() {
- // initialize the DbMap
- dbmap := initDb()
- defer dbmap.Db.Close()
-
- // delete any existing rows
- err := dbmap.TruncateTables()
- checkErr(err, "TruncateTables failed")
-
- // create two posts
- p1 := newPost("Go 1.1 released!", "Lorem ipsum lorem ipsum")
- p2 := newPost("Go 1.2 released!", "Lorem ipsum lorem ipsum")
-
- // insert rows - auto increment PKs will be set properly after the insert
- err = dbmap.Insert(&p1, &p2)
- checkErr(err, "Insert failed")
-
- // use convenience SelectInt
- count, err := dbmap.SelectInt("select count(*) from posts")
- checkErr(err, "select count(*) failed")
- log.Println("Rows after inserting:", count)
-
- // update a row
- p2.Title = "Go 1.2 is better than ever"
- count, err = dbmap.Update(&p2)
- checkErr(err, "Update failed")
- log.Println("Rows updated:", count)
-
- // fetch one row - note use of "post_id" instead of "Id" since column is aliased
- //
- // Postgres users should use $1 instead of ? placeholders
- // See 'Known Issues' below
- //
- err = dbmap.SelectOne(&p2, "select * from posts where post_id=?", p2.Id)
- checkErr(err, "SelectOne failed")
- log.Println("p2 row:", p2)
-
- // fetch all rows
- var posts []Post
- _, err = dbmap.Select(&posts, "select * from posts order by post_id")
- checkErr(err, "Select failed")
- log.Println("All rows:")
- for x, p := range posts {
- log.Printf(" %d: %v\n", x, p)
- }
-
- // delete row by PK
- count, err = dbmap.Delete(&p1)
- checkErr(err, "Delete failed")
- log.Println("Rows deleted:", count)
-
- // delete row manually via Exec
- _, err = dbmap.Exec("delete from posts where post_id=?", p2.Id)
- checkErr(err, "Exec failed")
-
- // confirm count is zero
- count, err = dbmap.SelectInt("select count(*) from posts")
- checkErr(err, "select count(*) failed")
- log.Println("Row count - should be zero:", count)
-
- log.Println("Done!")
-}
-
-type Post struct {
- // db tag lets you specify the column name if it differs from the struct field
- Id int64 `db:"post_id"`
- Created int64
- Title string `db:",size:50"` // Column size set to 50
- Body string `db:"article_body,size:1024"` // Set both column name and size
-}
-
-func newPost(title, body string) Post {
- return Post{
- Created: time.Now().UnixNano(),
- Title: title,
- Body: body,
- }
-}
-
-func initDb() *gorp.DbMap {
- // connect to db using standard Go database/sql API
- // use whatever database/sql driver you wish
- db, err := sql.Open("sqlite3", "/tmp/post_db.bin")
- checkErr(err, "sql.Open failed")
-
- // construct a gorp DbMap
- dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
-
- // add a table, setting the table name to 'posts' and
- // specifying that the Id property is an auto incrementing PK
- dbmap.AddTableWithName(Post{}, "posts").SetKeys(true, "Id")
-
- // create the table. in a production system you'd generally
- // use a migration tool, or create the tables via scripts
- err = dbmap.CreateTablesIfNotExists()
- checkErr(err, "Create tables failed")
-
- return dbmap
-}
-
-func checkErr(err error, msg string) {
- if err != nil {
- log.Fatalln(msg, err)
- }
-}
-```
-
-## Examples
-
-### Mapping structs to tables
-
-First define some types:
-
-```go
-type Invoice struct {
- Id int64
- Created int64
- Updated int64
- Memo string
- PersonId int64
-}
-
-type Person struct {
- Id int64
- Created int64
- Updated int64
- FName string
- LName string
-}
-
-// Example of using tags to alias fields to column names
-// The 'db' value is the column name
-//
-// A hyphen will cause gorp to skip this field, similar to the
-// Go json package.
-//
-// This is equivalent to using the ColMap methods:
-//
-// table := dbmap.AddTableWithName(Product{}, "product")
-// table.ColMap("Id").Rename("product_id")
-// table.ColMap("Price").Rename("unit_price")
-// table.ColMap("IgnoreMe").SetTransient(true)
-//
-// You can optionally declare the field to be a primary key and/or autoincrement
-//
-type Product struct {
- Id int64 `db:"product_id, primarykey, autoincrement"`
- Price int64 `db:"unit_price"`
- IgnoreMe string `db:"-"`
-}
-```
-
-Then create a mapper, typically you'd do this one time at app startup:
-
-```go
-// connect to db using standard Go database/sql API
-// use whatever database/sql driver you wish
-db, err := sql.Open("mymysql", "tcp:localhost:3306*mydb/myuser/mypassword")
-
-// construct a gorp DbMap
-dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
-
-// register the structs you wish to use with gorp
-// you can also use the shorter dbmap.AddTable() if you
-// don't want to override the table name
-//
-// SetKeys(true) means we have a auto increment primary key, which
-// will get automatically bound to your struct post-insert
-//
-t1 := dbmap.AddTableWithName(Invoice{}, "invoice_test").SetKeys(true, "Id")
-t2 := dbmap.AddTableWithName(Person{}, "person_test").SetKeys(true, "Id")
-t3 := dbmap.AddTableWithName(Product{}, "product_test").SetKeys(true, "Id")
-```
-
-### Struct Embedding
-
-gorp supports embedding structs. For example:
-
-```go
-type Names struct {
- FirstName string
- LastName string
-}
-
-type WithEmbeddedStruct struct {
- Id int64
- Names
-}
-
-es := &WithEmbeddedStruct{-1, Names{FirstName: "Alice", LastName: "Smith"}}
-err := dbmap.Insert(es)
-```
-
-See the `TestWithEmbeddedStruct` function in `gorp_test.go` for a full example.
-
-### Create/Drop Tables ###
-
-Automatically create / drop registered tables. This is useful for unit tests
-but is entirely optional. You can of course use gorp with tables created manually,
-or with a separate migration tool (like [goose](https://bitbucket.org/liamstask/goose) or [migrate](https://github.com/mattes/migrate)).
-
-```go
-// create all registered tables
-dbmap.CreateTables()
-
-// same as above, but uses "if not exists" clause to skip tables that are
-// already defined
-dbmap.CreateTablesIfNotExists()
-
-// drop
-dbmap.DropTables()
-```
-
-### SQL Logging
-
-Optionally you can pass in a logger to trace all SQL statements.
-I recommend enabling this initially while you're getting the feel for what
-gorp is doing on your behalf.
-
-Gorp defines a `GorpLogger` interface that Go's built in `log.Logger` satisfies.
-However, you can write your own `GorpLogger` implementation, or use a package such
-as `glog` if you want more control over how statements are logged.
-
-```go
-// Will log all SQL statements + args as they are run
-// The first arg is a string prefix to prepend to all log messages
-dbmap.TraceOn("[gorp]", log.New(os.Stdout, "myapp:", log.Lmicroseconds))
-
-// Turn off tracing
-dbmap.TraceOff()
-```
-
-### Insert
-
-```go
-// Must declare as pointers so optional callback hooks
-// can operate on your data, not copies
-inv1 := &Invoice{0, 100, 200, "first order", 0}
-inv2 := &Invoice{0, 100, 200, "second order", 0}
-
-// Insert your rows
-err := dbmap.Insert(inv1, inv2)
-
-// Because we called SetKeys(true) on Invoice, the Id field
-// will be populated after the Insert() automatically
-fmt.Printf("inv1.Id=%d inv2.Id=%d\n", inv1.Id, inv2.Id)
-```
-
-### Update
-
-Continuing the above example, use the `Update` method to modify an Invoice:
-
-```go
-// count is the # of rows updated, which should be 1 in this example
-count, err := dbmap.Update(inv1)
-```
-
-### Delete
-
-If you have primary key(s) defined for a struct, you can use the `Delete`
-method to remove rows:
-
-```go
-count, err := dbmap.Delete(inv1)
-```
-
-### Select by Key
-
-Use the `Get` method to fetch a single row by primary key. It returns
-nil if no row is found.
-
-```go
-// fetch Invoice with Id=99
-obj, err := dbmap.Get(Invoice{}, 99)
-inv := obj.(*Invoice)
-```
-
-### Ad Hoc SQL
-
-#### SELECT
-
-`Select()` and `SelectOne()` provide a simple way to bind arbitrary queries to a slice
-or a single struct.
-
-```go
-// Select a slice - first return value is not needed when a slice pointer is passed to Select()
-var posts []Post
-_, err := dbmap.Select(&posts, "select * from post order by id")
-
-// You can also use primitive types
-var ids []string
-_, err := dbmap.Select(&ids, "select id from post")
-
-// Select a single row.
-// Returns an error if no row found, or if more than one row is found
-var post Post
-err := dbmap.SelectOne(&post, "select * from post where id=?", id)
-```
-
-Want to do joins? Just write the SQL and the struct. gorp will bind them:
-
-```go
-// Define a type for your join
-// It *must* contain all the columns in your SELECT statement
-//
-// The names here should match the aliased column names you specify
-// in your SQL - no additional binding work required. simple.
-//
-type InvoicePersonView struct {
- InvoiceId int64
- PersonId int64
- Memo string
- FName string
-}
-
-// Create some rows
-p1 := &Person{0, 0, 0, "bob", "smith"}
-dbmap.Insert(p1)
-
-// notice how we can wire up p1.Id to the invoice easily
-inv1 := &Invoice{0, 0, 0, "xmas order", p1.Id}
-dbmap.Insert(inv1)
-
-// Run your query
-query := "select i.Id InvoiceId, p.Id PersonId, i.Memo, p.FName " +
- "from invoice_test i, person_test p " +
- "where i.PersonId = p.Id"
-
-// pass a slice to Select()
-var list []InvoicePersonView
-_, err := dbmap.Select(&list, query)
-
-// this should test true
-expected := InvoicePersonView{inv1.Id, p1.Id, inv1.Memo, p1.FName}
-if reflect.DeepEqual(list[0], expected) {
- fmt.Println("Woot! My join worked!")
-}
-```
-
-#### SELECT string or int64
-
-gorp provides a few convenience methods for selecting a single string or int64.
-
-```go
-// select single int64 from db (use $1 instead of ? for postgresql)
-i64, err := dbmap.SelectInt("select count(*) from foo where blah=?", blahVal)
-
-// select single string from db:
-s, err := dbmap.SelectStr("select name from foo where blah=?", blahVal)
-
-```
-
-#### Named bind parameters
-
-You may use a map or struct to bind parameters by name. This is currently
-only supported in SELECT queries.
-
-```go
-_, err := dbm.Select(&dest, "select * from Foo where name = :name and age = :age", map[string]interface{}{
- "name": "Rob",
- "age": 31,
-})
-```
-
-#### UPDATE / DELETE
-
-You can execute raw SQL if you wish. Particularly good for batch operations.
-
-```go
-res, err := dbmap.Exec("delete from invoice_test where PersonId=?", 10)
-```
-
-### Transactions
-
-You can batch operations into a transaction:
-
-```go
-func InsertInv(dbmap *DbMap, inv *Invoice, per *Person) error {
- // Start a new transaction
- trans, err := dbmap.Begin()
- if err != nil {
- return err
- }
-
- trans.Insert(per)
- inv.PersonId = per.Id
- trans.Insert(inv)
-
- // if the commit is successful, a nil error is returned
- return trans.Commit()
-}
-```
-
-### Hooks
-
-Use hooks to update data before/after saving to the db. Good for timestamps:
-
-```go
-// implement the PreInsert and PreUpdate hooks
-func (i *Invoice) PreInsert(s gorp.SqlExecutor) error {
- i.Created = time.Now().UnixNano()
- i.Updated = i.Created
- return nil
-}
-
-func (i *Invoice) PreUpdate(s gorp.SqlExecutor) error {
- i.Updated = time.Now().UnixNano()
- return nil
-}
-
-// You can use the SqlExecutor to cascade additional SQL
-// Take care to avoid cycles. gorp won't prevent them.
-//
-// Here's an example of a cascading delete
-//
-func (p *Person) PreDelete(s gorp.SqlExecutor) error {
- query := "delete from invoice_test where PersonId=?"
-
- _, err := s.Exec(query, p.Id)
-
- if err != nil {
- return err
- }
- return nil
-}
-```
-
-Full list of hooks that you can implement:
-
- PostGet
- PreInsert
- PostInsert
- PreUpdate
- PostUpdate
- PreDelete
- PostDelete
-
- All have the same signature. for example:
-
- func (p *MyStruct) PostUpdate(s gorp.SqlExecutor) error
-
-### Optimistic Locking
-
-#### Note that this behaviour has changed in v2. See [Migration Guide](#migration-guide).
-
-gorp provides a simple optimistic locking feature, similar to Java's JPA, that
-will raise an error if you try to update/delete a row whose `version` column
-has a value different than the one in memory. This provides a safe way to do
-"select then update" style operations without explicit read and write locks.
-
-```go
-// Version is an auto-incremented number, managed by gorp
-// If this property is present on your struct, update
-// operations will be constrained
-//
-// For example, say we defined Person as:
-
-type Person struct {
- Id int64
- Created int64
- Updated int64
- FName string
- LName string
-
- // automatically used as the Version col
- // use table.SetVersionCol("columnName") to map a different
- // struct field as the version field
- Version int64
-}
-
-p1 := &Person{0, 0, 0, "Bob", "Smith", 0}
-dbmap.Insert(p1) // Version is now 1
-
-obj, err := dbmap.Get(Person{}, p1.Id)
-p2 := obj.(*Person)
-p2.LName = "Edwards"
-dbmap.Update(p2) // Version is now 2
-
-p1.LName = "Howard"
-
-// Raises error because p1.Version == 1, which is out of date
-count, err := dbmap.Update(p1)
-_, ok := err.(gorp.OptimisticLockError)
-if ok {
- // should reach this statement
-
- // in a real app you might reload the row and retry, or
- // you might propegate this to the user, depending on the desired
- // semantics
- fmt.Printf("Tried to update row with stale data: %v\n", err)
-} else {
- // some other db error occurred - log or return up the stack
- fmt.Printf("Unknown db err: %v\n", err)
-}
-```
-### Adding INDEX(es) on column(s) beyond the primary key ###
-
-Indexes are frequently critical for performance. Here is how to add them to your tables.
-
-NB: SqlServer and Oracle need testing and possible adjustment to the
-CreateIndexSuffix() and DropIndexSuffix() methods to make AddIndex()
-work for them.
-
-In the example below we put an index both on the Id field, and on the AcctId field.
-
-```
-type Account struct {
- Id int64
- AcctId string // e.g. this might be a long uuid for portability
-}
-
-// indexType (the 2nd param to AddIndex call) is "Btree" or "Hash" for MySQL.
-// demonstrate adding a second index on AcctId, and constrain that field to have unique values.
-dbm.AddTable(iptab.Account{}).SetKeys(true, "Id").AddIndex("AcctIdIndex", "Btree", []string{"AcctId"}).SetUnique(true)
-
-err = dbm.CreateTablesIfNotExists()
-checkErr(err, "CreateTablesIfNotExists failed")
-
-err = dbm.CreateIndex()
-checkErr(err, "CreateIndex failed")
-
-```
-Check the effect of the CreateIndex() call in mysql:
-```
-$ mysql
-
-MariaDB [test]> show create table Account;
-+---------+--------------------------+
-| Account | CREATE TABLE `Account` (
- `Id` bigint(20) NOT NULL AUTO_INCREMENT,
- `AcctId` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`Id`),
- UNIQUE KEY `AcctIdIndex` (`AcctId`) USING BTREE <<<--- yes! index added.
-) ENGINE=InnoDB DEFAULT CHARSET=utf8
-+---------+--------------------------+
-
-```
-
-
-## Database Drivers
-
-gorp uses the Go 1 `database/sql` package. A full list of compliant drivers is available here:
-
-http://code.google.com/p/go-wiki/wiki/SQLDrivers
-
-Sadly, SQL databases differ on various issues. gorp provides a Dialect interface that should be
-implemented per database vendor. Dialects are provided for:
-
-* MySQL
-* PostgreSQL
-* sqlite3
-
-Each of these three databases pass the test suite. See `gorp_test.go` for example
-DSNs for these three databases.
-
-Support is also provided for:
-
-* Oracle (contributed by @klaidliadon)
-* SQL Server (contributed by @qrawl) - use driver: github.com/denisenkom/go-mssqldb
-
-Note that these databases are not covered by CI and I (@coopernurse) have no good way to
-test them locally. So please try them and send patches as needed, but expect a bit more
-unpredicability.
-
-## Known Issues
-
-### SQL placeholder portability
-
-Different databases use different strings to indicate variable placeholders in
-prepared SQL statements. Unlike some database abstraction layers (such as JDBC),
-Go's `database/sql` does not standardize this.
-
-SQL generated by gorp in the `Insert`, `Update`, `Delete`, and `Get` methods delegates
-to a Dialect implementation for each database, and will generate portable SQL.
-
-Raw SQL strings passed to `Exec`, `Select`, `SelectOne`, `SelectInt`, etc will not be
-parsed. Consequently you may have portability issues if you write a query like this:
-
-```go
-// works on MySQL and Sqlite3, but not with Postgresql
-err := dbmap.SelectOne(&val, "select * from foo where id = ?", 30)
-```
-
-In `Select` and `SelectOne` you can use named parameters to work around this.
-The following is portable:
-
-```go
-err := dbmap.SelectOne(&val, "select * from foo where id = :id",
- map[string]interface{} { "id": 30})
-```
-
-Additionally, when using Postgres as your database, you should utilize `$1` instead
-of `?` placeholders as utilizing `?` placeholders when querying Postgres will result
-in `pq: operator does not exist` errors. Alternatively, use
-`dbMap.Dialect.BindVar(varIdx)` to get the proper variable binding for your dialect.
-
-### time.Time and time zones
-
-gorp will pass `time.Time` fields through to the `database/sql` driver, but note that
-the behavior of this type varies across database drivers.
-
-MySQL users should be especially cautious. See: https://github.com/ziutek/mymysql/pull/77
-
-To avoid any potential issues with timezone/DST, consider using an integer field for time
-data and storing UNIX time.
-
-## Running the tests
-
-The included tests may be run against MySQL, Postgresql, or sqlite3.
-You must set two environment variables so the test code knows which driver to
-use, and how to connect to your database.
-
-```sh
-# MySQL example:
-export GORP_TEST_DSN=gomysql_test/gomysql_test/abc123
-export GORP_TEST_DIALECT=mysql
-
-# run the tests
-go test
-
-# run the tests and benchmarks
-go test -bench="Bench" -benchtime 10
-```
-
-Valid `GORP_TEST_DIALECT` values are: "mysql"(for mymysql), "gomysql"(for go-sql-driver), "postgres", "sqlite"
-See the `test_all.sh` script for examples of all 3 databases. This is the script I run
-locally to test the library.
-
-## Performance
-
-gorp uses reflection to construct SQL queries and bind parameters. See the BenchmarkNativeCrud vs BenchmarkGorpCrud in gorp_test.go for a simple perf test. On my MacBook Pro gorp is about 2-3% slower than hand written SQL.
-
-## Migration guide
-#### Pre-v2 to v2
-Automatic mapping of the version column used in optimistic locking has been removed as it could cause problems if the type was not int. The version column must now explicitly be set with tablemap.SetVersionCol().
-
-## Help/Support
-
-IRC: #gorp
-Mailing list: gorp-dev@googlegroups.com
-Bugs/Enhancements: Create a github issue
-
-## Pull requests / Contributions
-
-Contributions are very welcome. Please follow these guidelines:
-
-* Fork the `master` branch and issue pull requests targeting the `master` branch
-* If you are adding an enhancement, please open an issue first with your proposed change.
-* Changes that break backwards compatibility in the public API are only accepted after we
- discuss on a GitHub issue for a while.
-
-Thanks!
-
-## Contributors
-
-* matthias-margush - column aliasing via tags
-* Rob Figueiredo - @robfig
-* Quinn Slack - @sqs
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/column.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/column.go
deleted file mode 100644
index 99d4fd555..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/column.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import "reflect"
-
-// ColumnMap represents a mapping between a Go struct field and a single
-// column in a table.
-// Unique and MaxSize only inform the
-// CreateTables() function and are not used by Insert/Update/Delete/Get.
-type ColumnMap struct {
- // Column name in db table
- ColumnName string
-
- // If true, this column is skipped in generated SQL statements
- Transient bool
-
- // If true, " unique" is added to create table statements.
- // Not used elsewhere
- Unique bool
-
- // Query used for getting generated id after insert
- GeneratedIdQuery string
-
- // Passed to Dialect.ToSqlType() to assist in informing the
- // correct column type to map to in CreateTables()
- MaxSize int
-
- DefaultValue string
-
- fieldName string
- gotype reflect.Type
- isPK bool
- isAutoIncr bool
- isNotNull bool
-}
-
-// Rename allows you to specify the column name in the table
-//
-// Example: table.ColMap("Updated").Rename("date_updated")
-//
-func (c *ColumnMap) Rename(colname string) *ColumnMap {
- c.ColumnName = colname
- return c
-}
-
-// SetTransient allows you to mark the column as transient. If true
-// this column will be skipped when SQL statements are generated
-func (c *ColumnMap) SetTransient(b bool) *ColumnMap {
- c.Transient = b
- return c
-}
-
-// SetUnique adds "unique" to the create table statements for this
-// column, if b is true.
-func (c *ColumnMap) SetUnique(b bool) *ColumnMap {
- c.Unique = b
- return c
-}
-
-// SetNotNull adds "not null" to the create table statements for this
-// column, if nn is true.
-func (c *ColumnMap) SetNotNull(nn bool) *ColumnMap {
- c.isNotNull = nn
- return c
-}
-
-// SetMaxSize specifies the max length of values of this column. This is
-// passed to the dialect.ToSqlType() function, which can use the value
-// to alter the generated type for "create table" statements
-func (c *ColumnMap) SetMaxSize(size int) *ColumnMap {
- c.MaxSize = size
- return c
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/db.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/db.go
deleted file mode 100644
index 8bba07cf6..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/db.go
+++ /dev/null
@@ -1,619 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "bytes"
- "database/sql"
- "database/sql/driver"
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-// DbMap is the root gorp mapping object. Create one of these for each
-// database schema you wish to map. Each DbMap contains a list of
-// mapped tables.
-//
-// Example:
-//
-// dialect := gorp.MySQLDialect{"InnoDB", "UTF8"}
-// dbmap := &gorp.DbMap{Db: db, Dialect: dialect}
-//
-type DbMap struct {
- // Db handle to use with this map
- Db *sql.DB
-
- // Dialect implementation to use with this map
- Dialect Dialect
-
- TypeConverter TypeConverter
-
- tables []*TableMap
- logger GorpLogger
- logPrefix string
-}
-
-func (m *DbMap) CreateIndex() error {
-
- var err error
- dialect := reflect.TypeOf(m.Dialect)
- for _, table := range m.tables {
- for _, index := range table.indexes {
-
- s := bytes.Buffer{}
- s.WriteString("create")
- if index.Unique {
- s.WriteString(" unique")
- }
- s.WriteString(" index")
- s.WriteString(fmt.Sprintf(" %s on %s", index.IndexName, table.TableName))
- if dname := dialect.Name(); dname == "PostgresDialect" && index.IndexType != "" {
- s.WriteString(fmt.Sprintf(" %s %s", m.Dialect.CreateIndexSuffix(), index.IndexType))
- }
- s.WriteString(" (")
- for x, col := range index.columns {
- if x > 0 {
- s.WriteString(", ")
- }
- s.WriteString(m.Dialect.QuoteField(col))
- }
- s.WriteString(")")
-
- if dname := dialect.Name(); dname == "MySQLDialect" && index.IndexType != "" {
- s.WriteString(fmt.Sprintf(" %s %s", m.Dialect.CreateIndexSuffix(), index.IndexType))
- }
- s.WriteString(";")
- _, err = m.Exec(s.String())
- if err != nil {
- break
- }
- }
- }
- return err
-}
-
-func (t *TableMap) DropIndex(name string) error {
-
- var err error
- dialect := reflect.TypeOf(t.dbmap.Dialect)
- for _, idx := range t.indexes {
- if idx.IndexName == name {
- s := bytes.Buffer{}
- s.WriteString(fmt.Sprintf("DROP INDEX %s", idx.IndexName))
-
- if dname := dialect.Name(); dname == "MySQLDialect" {
- s.WriteString(fmt.Sprintf(" %s %s", t.dbmap.Dialect.DropIndexSuffix(), t.TableName))
- }
- s.WriteString(";")
- _, e := t.dbmap.Exec(s.String())
- if e != nil {
- err = e
- }
- break
- }
- }
- t.ResetSql()
- return err
-}
-
-// AddTable registers the given interface type with gorp. The table name
-// will be given the name of the TypeOf(i). You must call this function,
-// or AddTableWithName, for any struct type you wish to persist with
-// the given DbMap.
-//
-// This operation is idempotent. If i's type is already mapped, the
-// existing *TableMap is returned
-func (m *DbMap) AddTable(i interface{}) *TableMap {
- return m.AddTableWithName(i, "")
-}
-
-// AddTableWithName has the same behavior as AddTable, but sets
-// table.TableName to name.
-func (m *DbMap) AddTableWithName(i interface{}, name string) *TableMap {
- return m.AddTableWithNameAndSchema(i, "", name)
-}
-
-// AddTableWithNameAndSchema has the same behavior as AddTable, but sets
-// table.TableName to name.
-func (m *DbMap) AddTableWithNameAndSchema(i interface{}, schema string, name string) *TableMap {
- t := reflect.TypeOf(i)
- if name == "" {
- name = t.Name()
- }
-
- // check if we have a table for this type already
- // if so, update the name and return the existing pointer
- for i := range m.tables {
- table := m.tables[i]
- if table.gotype == t {
- table.TableName = name
- return table
- }
- }
-
- tmap := &TableMap{gotype: t, TableName: name, SchemaName: schema, dbmap: m}
- var primaryKey []*ColumnMap
- tmap.Columns, primaryKey = m.readStructColumns(t)
- m.tables = append(m.tables, tmap)
- if len(primaryKey) > 0 {
- tmap.keys = append(tmap.keys, primaryKey...)
- }
-
- return tmap
-}
-
-func (m *DbMap) readStructColumns(t reflect.Type) (cols []*ColumnMap, primaryKey []*ColumnMap) {
- primaryKey = make([]*ColumnMap, 0)
- n := t.NumField()
- for i := 0; i < n; i++ {
- f := t.Field(i)
- if f.Anonymous && f.Type.Kind() == reflect.Struct {
- // Recursively add nested fields in embedded structs.
- subcols, subpk := m.readStructColumns(f.Type)
- // Don't append nested fields that have the same field
- // name as an already-mapped field.
- for _, subcol := range subcols {
- shouldAppend := true
- for _, col := range cols {
- if !subcol.Transient && subcol.fieldName == col.fieldName {
- shouldAppend = false
- break
- }
- }
- if shouldAppend {
- cols = append(cols, subcol)
- }
- }
- if subpk != nil {
- primaryKey = append(primaryKey, subpk...)
- }
- } else {
- // Tag = Name { ',' Option }
- // Option = OptionKey [ ':' OptionValue ]
- cArguments := strings.Split(f.Tag.Get("db"), ",")
- columnName := cArguments[0]
- var maxSize int
- var defaultValue string
- var isAuto bool
- var isPK bool
- for _, argString := range cArguments[1:] {
- argString = strings.TrimSpace(argString)
- arg := strings.SplitN(argString, ":", 2)
-
- // check mandatory/unexpected option values
- switch arg[0] {
- case "size", "default":
- // options requiring value
- if len(arg) == 1 {
- panic(fmt.Sprintf("missing option value for option %v on field %v", arg[0], f.Name))
- }
- default:
- // options where value is invalid (currently all other options)
- if len(arg) == 2 {
- panic(fmt.Sprintf("unexpected option value for option %v on field %v", arg[0], f.Name))
- }
- }
-
- switch arg[0] {
- case "size":
- maxSize, _ = strconv.Atoi(arg[1])
- case "default":
- defaultValue = arg[1]
- case "primarykey":
- isPK = true
- case "autoincrement":
- isAuto = true
- default:
- panic(fmt.Sprintf("Unrecognized tag option for field %v: %v", f.Name, arg))
- }
- }
- if columnName == "" {
- columnName = f.Name
- }
-
- gotype := f.Type
- value := reflect.New(gotype).Interface()
- if m.TypeConverter != nil {
- // Make a new pointer to a value of type gotype and
- // pass it to the TypeConverter's FromDb method to see
- // if a different type should be used for the column
- // type during table creation.
- scanner, useHolder := m.TypeConverter.FromDb(value)
- if useHolder {
- value = scanner.Holder
- gotype = reflect.TypeOf(value)
- }
- }
- if typer, ok := value.(SqlTyper); ok {
- gotype = reflect.TypeOf(typer.SqlType())
- } else if valuer, ok := value.(driver.Valuer); ok {
- // Only check for driver.Valuer if SqlTyper wasn't
- // found.
- v, err := valuer.Value()
- if err == nil && v != nil {
- gotype = reflect.TypeOf(v)
- }
- }
- cm := &ColumnMap{
- ColumnName: columnName,
- DefaultValue: defaultValue,
- Transient: columnName == "-",
- fieldName: f.Name,
- gotype: gotype,
- isPK: isPK,
- isAutoIncr: isAuto,
- MaxSize: maxSize,
- }
- if isPK {
- primaryKey = append(primaryKey, cm)
- }
- // Check for nested fields of the same field name and
- // override them.
- shouldAppend := true
- for index, col := range cols {
- if !col.Transient && col.fieldName == cm.fieldName {
- cols[index] = cm
- shouldAppend = false
- break
- }
- }
- if shouldAppend {
- cols = append(cols, cm)
- }
- }
-
- }
- return
-}
-
-// CreateTables iterates through TableMaps registered to this DbMap and
-// executes "create table" statements against the database for each.
-//
-// This is particularly useful in unit tests where you want to create
-// and destroy the schema automatically.
-func (m *DbMap) CreateTables() error {
- return m.createTables(false)
-}
-
-// CreateTablesIfNotExists is similar to CreateTables, but starts
-// each statement with "create table if not exists" so that existing
-// tables do not raise errors
-func (m *DbMap) CreateTablesIfNotExists() error {
- return m.createTables(true)
-}
-
-func (m *DbMap) createTables(ifNotExists bool) error {
- var err error
- for i := range m.tables {
- table := m.tables[i]
- sql := table.SqlForCreate(ifNotExists)
- _, err = m.Exec(sql)
- if err != nil {
- break
- }
- }
- return err
-}
-
-// DropTable drops an individual table.
-// Returns an error when the table does not exist.
-func (m *DbMap) DropTable(table interface{}) error {
- t := reflect.TypeOf(table)
- return m.dropTable(t, false)
-}
-
-// DropTableIfExists drops an individual table when the table exists.
-func (m *DbMap) DropTableIfExists(table interface{}) error {
- t := reflect.TypeOf(table)
- return m.dropTable(t, true)
-}
-
-// DropTables iterates through TableMaps registered to this DbMap and
-// executes "drop table" statements against the database for each.
-func (m *DbMap) DropTables() error {
- return m.dropTables(false)
-}
-
-// DropTablesIfExists is the same as DropTables, but uses the "if exists" clause to
-// avoid errors for tables that do not exist.
-func (m *DbMap) DropTablesIfExists() error {
- return m.dropTables(true)
-}
-
-// Goes through all the registered tables, dropping them one by one.
-// If an error is encountered, then it is returned and the rest of
-// the tables are not dropped.
-func (m *DbMap) dropTables(addIfExists bool) (err error) {
- for _, table := range m.tables {
- err = m.dropTableImpl(table, addIfExists)
- if err != nil {
- return err
- }
- }
- return err
-}
-
-// Implementation of dropping a single table.
-func (m *DbMap) dropTable(t reflect.Type, addIfExists bool) error {
- table := tableOrNil(m, t)
- if table == nil {
- return fmt.Errorf("table %s was not registered", table.TableName)
- }
-
- return m.dropTableImpl(table, addIfExists)
-}
-
-func (m *DbMap) dropTableImpl(table *TableMap, ifExists bool) (err error) {
- tableDrop := "drop table"
- if ifExists {
- tableDrop = m.Dialect.IfTableExists(tableDrop, table.SchemaName, table.TableName)
- }
- _, err = m.Exec(fmt.Sprintf("%s %s;", tableDrop, m.Dialect.QuotedTableForQuery(table.SchemaName, table.TableName)))
- return err
-}
-
-// TruncateTables iterates through TableMaps registered to this DbMap and
-// executes "truncate table" statements against the database for each, or in the case of
-// sqlite, a "delete from" with no "where" clause, which uses the truncate optimization
-// (http://www.sqlite.org/lang_delete.html)
-func (m *DbMap) TruncateTables() error {
- var err error
- for i := range m.tables {
- table := m.tables[i]
- _, e := m.Exec(fmt.Sprintf("%s %s;", m.Dialect.TruncateClause(), m.Dialect.QuotedTableForQuery(table.SchemaName, table.TableName)))
- if e != nil {
- err = e
- }
- }
- return err
-}
-
-// Insert runs a SQL INSERT statement for each element in list. List
-// items must be pointers.
-//
-// Any interface whose TableMap has an auto-increment primary key will
-// have its last insert id bound to the PK field on the struct.
-//
-// The hook functions PreInsert() and/or PostInsert() will be executed
-// before/after the INSERT statement if the interface defines them.
-//
-// Panics if any interface in the list has not been registered with AddTable
-func (m *DbMap) Insert(list ...interface{}) error {
- return insert(m, m, list...)
-}
-
-// Update runs a SQL UPDATE statement for each element in list. List
-// items must be pointers.
-//
-// The hook functions PreUpdate() and/or PostUpdate() will be executed
-// before/after the UPDATE statement if the interface defines them.
-//
-// Returns the number of rows updated.
-//
-// Returns an error if SetKeys has not been called on the TableMap
-// Panics if any interface in the list has not been registered with AddTable
-func (m *DbMap) Update(list ...interface{}) (int64, error) {
- return update(m, m, nil, list...)
-}
-
-// UpdateColumns runs a SQL UPDATE statement for each element in list. List
-// items must be pointers.
-//
-// Only the columns accepted by filter are included in the UPDATE.
-//
-// The hook functions PreUpdate() and/or PostUpdate() will be executed
-// before/after the UPDATE statement if the interface defines them.
-//
-// Returns the number of rows updated.
-//
-// Returns an error if SetKeys has not been called on the TableMap
-// Panics if any interface in the list has not been registered with AddTable
-func (m *DbMap) UpdateColumns(filter ColumnFilter, list ...interface{}) (int64, error) {
- return update(m, m, filter, list...)
-}
-
-// Delete runs a SQL DELETE statement for each element in list. List
-// items must be pointers.
-//
-// The hook functions PreDelete() and/or PostDelete() will be executed
-// before/after the DELETE statement if the interface defines them.
-//
-// Returns the number of rows deleted.
-//
-// Returns an error if SetKeys has not been called on the TableMap
-// Panics if any interface in the list has not been registered with AddTable
-func (m *DbMap) Delete(list ...interface{}) (int64, error) {
- return delete(m, m, list...)
-}
-
-// Get runs a SQL SELECT to fetch a single row from the table based on the
-// primary key(s)
-//
-// i should be an empty value for the struct to load. keys should be
-// the primary key value(s) for the row to load. If multiple keys
-// exist on the table, the order should match the column order
-// specified in SetKeys() when the table mapping was defined.
-//
-// The hook function PostGet() will be executed after the SELECT
-// statement if the interface defines them.
-//
-// Returns a pointer to a struct that matches or nil if no row is found.
-//
-// Returns an error if SetKeys has not been called on the TableMap
-// Panics if any interface in the list has not been registered with AddTable
-func (m *DbMap) Get(i interface{}, keys ...interface{}) (interface{}, error) {
- return get(m, m, i, keys...)
-}
-
-// Select runs an arbitrary SQL query, binding the columns in the result
-// to fields on the struct specified by i. args represent the bind
-// parameters for the SQL statement.
-//
-// Column names on the SELECT statement should be aliased to the field names
-// on the struct i. Returns an error if one or more columns in the result
-// do not match. It is OK if fields on i are not part of the SQL
-// statement.
-//
-// The hook function PostGet() will be executed after the SELECT
-// statement if the interface defines them.
-//
-// Values are returned in one of two ways:
-// 1. If i is a struct or a pointer to a struct, returns a slice of pointers to
-// matching rows of type i.
-// 2. If i is a pointer to a slice, the results will be appended to that slice
-// and nil returned.
-//
-// i does NOT need to be registered with AddTable()
-func (m *DbMap) Select(i interface{}, query string, args ...interface{}) ([]interface{}, error) {
- return hookedselect(m, m, i, query, args...)
-}
-
-// Exec runs an arbitrary SQL statement. args represent the bind parameters.
-// This is equivalent to running: Exec() using database/sql
-func (m *DbMap) Exec(query string, args ...interface{}) (sql.Result, error) {
- if m.logger != nil {
- now := time.Now()
- defer m.trace(now, query, args...)
- }
- return exec(m, query, args...)
-}
-
-// SelectInt is a convenience wrapper around the gorp.SelectInt function
-func (m *DbMap) SelectInt(query string, args ...interface{}) (int64, error) {
- return SelectInt(m, query, args...)
-}
-
-// SelectNullInt is a convenience wrapper around the gorp.SelectNullInt function
-func (m *DbMap) SelectNullInt(query string, args ...interface{}) (sql.NullInt64, error) {
- return SelectNullInt(m, query, args...)
-}
-
-// SelectFloat is a convenience wrapper around the gorp.SelectFloat function
-func (m *DbMap) SelectFloat(query string, args ...interface{}) (float64, error) {
- return SelectFloat(m, query, args...)
-}
-
-// SelectNullFloat is a convenience wrapper around the gorp.SelectNullFloat function
-func (m *DbMap) SelectNullFloat(query string, args ...interface{}) (sql.NullFloat64, error) {
- return SelectNullFloat(m, query, args...)
-}
-
-// SelectStr is a convenience wrapper around the gorp.SelectStr function
-func (m *DbMap) SelectStr(query string, args ...interface{}) (string, error) {
- return SelectStr(m, query, args...)
-}
-
-// SelectNullStr is a convenience wrapper around the gorp.SelectNullStr function
-func (m *DbMap) SelectNullStr(query string, args ...interface{}) (sql.NullString, error) {
- return SelectNullStr(m, query, args...)
-}
-
-// SelectOne is a convenience wrapper around the gorp.SelectOne function
-func (m *DbMap) SelectOne(holder interface{}, query string, args ...interface{}) error {
- return SelectOne(m, m, holder, query, args...)
-}
-
-// Begin starts a gorp Transaction
-func (m *DbMap) Begin() (*Transaction, error) {
- if m.logger != nil {
- now := time.Now()
- defer m.trace(now, "begin;")
- }
- tx, err := m.Db.Begin()
- if err != nil {
- return nil, err
- }
- return &Transaction{m, tx, false}, nil
-}
-
-// TableFor returns the *TableMap corresponding to the given Go Type
-// If no table is mapped to that type an error is returned.
-// If checkPK is true and the mapped table has no registered PKs, an error is returned.
-func (m *DbMap) TableFor(t reflect.Type, checkPK bool) (*TableMap, error) {
- table := tableOrNil(m, t)
- if table == nil {
- return nil, fmt.Errorf("no table found for type: %v", t.Name())
- }
-
- if checkPK && len(table.keys) < 1 {
- e := fmt.Sprintf("gorp: no keys defined for table: %s",
- table.TableName)
- return nil, errors.New(e)
- }
-
- return table, nil
-}
-
-// Prepare creates a prepared statement for later queries or executions.
-// Multiple queries or executions may be run concurrently from the returned statement.
-// This is equivalent to running: Prepare() using database/sql
-func (m *DbMap) Prepare(query string) (*sql.Stmt, error) {
- if m.logger != nil {
- now := time.Now()
- defer m.trace(now, query, nil)
- }
- return m.Db.Prepare(query)
-}
-
-func tableOrNil(m *DbMap, t reflect.Type) *TableMap {
- for i := range m.tables {
- table := m.tables[i]
- if table.gotype == t {
- return table
- }
- }
- return nil
-}
-
-func (m *DbMap) tableForPointer(ptr interface{}, checkPK bool) (*TableMap, reflect.Value, error) {
- ptrv := reflect.ValueOf(ptr)
- if ptrv.Kind() != reflect.Ptr {
- e := fmt.Sprintf("gorp: passed non-pointer: %v (kind=%v)", ptr,
- ptrv.Kind())
- return nil, reflect.Value{}, errors.New(e)
- }
- elem := ptrv.Elem()
- etype := reflect.TypeOf(elem.Interface())
- t, err := m.TableFor(etype, checkPK)
- if err != nil {
- return nil, reflect.Value{}, err
- }
-
- return t, elem, nil
-}
-
-func (m *DbMap) queryRow(query string, args ...interface{}) *sql.Row {
- if m.logger != nil {
- now := time.Now()
- defer m.trace(now, query, args...)
- }
- return m.Db.QueryRow(query, args...)
-}
-
-func (m *DbMap) query(query string, args ...interface{}) (*sql.Rows, error) {
- if m.logger != nil {
- now := time.Now()
- defer m.trace(now, query, args...)
- }
- return m.Db.Query(query, args...)
-}
-
-func (m *DbMap) trace(started time.Time, query string, args ...interface{}) {
- if m.logger != nil {
- var margs = argsString(args...)
- m.logger.Printf("%s%s [%s] (%v)", m.logPrefix, query, margs, (time.Now().Sub(started)))
- }
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect.go
deleted file mode 100644
index 203bc62b5..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import "reflect"
-
-// The Dialect interface encapsulates behaviors that differ across
-// SQL databases. At present the Dialect is only used by CreateTables()
-// but this could change in the future
-type Dialect interface {
-
- // adds a suffix to any query, usually ";"
- QuerySuffix() string
-
- // ToSqlType returns the SQL column type to use when creating a
- // table of the given Go Type. maxsize can be used to switch based on
- // size. For example, in MySQL []byte could map to BLOB, MEDIUMBLOB,
- // or LONGBLOB depending on the maxsize
- ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string
-
- // string to append to primary key column definitions
- AutoIncrStr() string
-
- // string to bind autoincrement columns to. Empty string will
- // remove reference to those columns in the INSERT statement.
- AutoIncrBindValue() string
-
- AutoIncrInsertSuffix(col *ColumnMap) string
-
- // string to append to "create table" statement for vendor specific
- // table attributes
- CreateTableSuffix() string
-
- // string to append to "create index" statement
- CreateIndexSuffix() string
-
- // string to append to "drop index" statement
- DropIndexSuffix() string
-
- // string to truncate tables
- TruncateClause() string
-
- // bind variable string to use when forming SQL statements
- // in many dbs it is "?", but Postgres appears to use $1
- //
- // i is a zero based index of the bind variable in this statement
- //
- BindVar(i int) string
-
- // Handles quoting of a field name to ensure that it doesn't raise any
- // SQL parsing exceptions by using a reserved word as a field name.
- QuoteField(field string) string
-
- // Handles building up of a schema.database string that is compatible with
- // the given dialect
- //
- // schema - The schema that <table> lives in
- // table - The table name
- QuotedTableForQuery(schema string, table string) string
-
- // Existance clause for table creation / deletion
- IfSchemaNotExists(command, schema string) string
- IfTableExists(command, schema, table string) string
- IfTableNotExists(command, schema, table string) string
-}
-
-// IntegerAutoIncrInserter is implemented by dialects that can perform
-// inserts with automatically incremented integer primary keys. If
-// the dialect can handle automatic assignment of more than just
-// integers, see TargetedAutoIncrInserter.
-type IntegerAutoIncrInserter interface {
- InsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error)
-}
-
-// TargetedAutoIncrInserter is implemented by dialects that can
-// perform automatic assignment of any primary key type (i.e. strings
-// for uuids, integers for serials, etc).
-type TargetedAutoIncrInserter interface {
- // InsertAutoIncrToTarget runs an insert operation and assigns the
- // automatically generated primary key directly to the passed in
- // target. The target should be a pointer to the primary key
- // field of the value being inserted.
- InsertAutoIncrToTarget(exec SqlExecutor, insertSql string, target interface{}, params ...interface{}) error
-}
-
-// TargetQueryInserter is implemented by dialects that can perform
-// assignment of integer primary key type by executing a query
-// like "select sequence.currval from dual".
-type TargetQueryInserter interface {
- // TargetQueryInserter runs an insert operation and assigns the
- // automatically generated primary key retrived by the query
- // extracted from the GeneratedIdQuery field of the id column.
- InsertQueryToTarget(exec SqlExecutor, insertSql, idSql string, target interface{}, params ...interface{}) error
-}
-
-func standardInsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error) {
- res, err := exec.Exec(insertSql, params...)
- if err != nil {
- return 0, err
- }
- return res.LastInsertId()
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_mysql.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_mysql.go
deleted file mode 100644
index 3d7d34027..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_mysql.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-// Implementation of Dialect for MySQL databases.
-type MySQLDialect struct {
-
- // Engine is the storage engine to use "InnoDB" vs "MyISAM" for example
- Engine string
-
- // Encoding is the character encoding to use for created tables
- Encoding string
-}
-
-func (d MySQLDialect) QuerySuffix() string { return ";" }
-
-func (d MySQLDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
- switch val.Kind() {
- case reflect.Ptr:
- return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
- case reflect.Bool:
- return "boolean"
- case reflect.Int8:
- return "tinyint"
- case reflect.Uint8:
- return "tinyint unsigned"
- case reflect.Int16:
- return "smallint"
- case reflect.Uint16:
- return "smallint unsigned"
- case reflect.Int, reflect.Int32:
- return "int"
- case reflect.Uint, reflect.Uint32:
- return "int unsigned"
- case reflect.Int64:
- return "bigint"
- case reflect.Uint64:
- return "bigint unsigned"
- case reflect.Float64, reflect.Float32:
- return "double"
- case reflect.Slice:
- if val.Elem().Kind() == reflect.Uint8 {
- return "mediumblob"
- }
- }
-
- switch val.Name() {
- case "NullInt64":
- return "bigint"
- case "NullFloat64":
- return "double"
- case "NullBool":
- return "tinyint"
- case "Time":
- return "datetime"
- }
-
- if maxsize < 1 {
- maxsize = 255
- }
-
- /* == About varchar(N) ==
- * N is number of characters.
- * A varchar column can store up to 65535 bytes.
- * Remember that 1 character is 3 bytes in utf-8 charset.
- * Also remember that each row can store up to 65535 bytes,
- * and you have some overheads, so it's not possible for a
- * varchar column to have 65535/3 characters really.
- * So it would be better to use 'text' type in stead of
- * large varchar type.
- */
- if maxsize < 256 {
- return fmt.Sprintf("varchar(%d)", maxsize)
- } else {
- return "text"
- }
-}
-
-// Returns auto_increment
-func (d MySQLDialect) AutoIncrStr() string {
- return "auto_increment"
-}
-
-func (d MySQLDialect) AutoIncrBindValue() string {
- return "null"
-}
-
-func (d MySQLDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
- return ""
-}
-
-// Returns engine=%s charset=%s based on values stored on struct
-func (d MySQLDialect) CreateTableSuffix() string {
- if d.Engine == "" || d.Encoding == "" {
- msg := "gorp - undefined"
-
- if d.Engine == "" {
- msg += " MySQLDialect.Engine"
- }
- if d.Engine == "" && d.Encoding == "" {
- msg += ","
- }
- if d.Encoding == "" {
- msg += " MySQLDialect.Encoding"
- }
- msg += ". Check that your MySQLDialect was correctly initialized when declared."
- panic(msg)
- }
-
- return fmt.Sprintf(" engine=%s charset=%s", d.Engine, d.Encoding)
-}
-
-func (m MySQLDialect) CreateIndexSuffix() string {
- return "using"
-}
-
-func (m MySQLDialect) DropIndexSuffix() string {
- return "on"
-}
-
-func (m MySQLDialect) TruncateClause() string {
- return "truncate"
-}
-
-// Returns "?"
-func (d MySQLDialect) BindVar(i int) string {
- return "?"
-}
-
-func (d MySQLDialect) InsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error) {
- return standardInsertAutoIncr(exec, insertSql, params...)
-}
-
-func (d MySQLDialect) QuoteField(f string) string {
- return "`" + f + "`"
-}
-
-func (d MySQLDialect) QuotedTableForQuery(schema string, table string) string {
- if strings.TrimSpace(schema) == "" {
- return d.QuoteField(table)
- }
-
- return schema + "." + d.QuoteField(table)
-}
-
-func (d MySQLDialect) IfSchemaNotExists(command, schema string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
-
-func (d MySQLDialect) IfTableExists(command, schema, table string) string {
- return fmt.Sprintf("%s if exists", command)
-}
-
-func (d MySQLDialect) IfTableNotExists(command, schema, table string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_oracle.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_oracle.go
deleted file mode 100644
index c381380f9..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_oracle.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-// Implementation of Dialect for Oracle databases.
-type OracleDialect struct{}
-
-func (d OracleDialect) QuerySuffix() string { return "" }
-
-func (d OracleDialect) CreateIndexSuffix() string { return "" }
-
-func (d OracleDialect) DropIndexSuffix() string { return "" }
-
-func (d OracleDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
- switch val.Kind() {
- case reflect.Ptr:
- return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
- case reflect.Bool:
- return "boolean"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
- if isAutoIncr {
- return "serial"
- }
- return "integer"
- case reflect.Int64, reflect.Uint64:
- if isAutoIncr {
- return "bigserial"
- }
- return "bigint"
- case reflect.Float64:
- return "double precision"
- case reflect.Float32:
- return "real"
- case reflect.Slice:
- if val.Elem().Kind() == reflect.Uint8 {
- return "bytea"
- }
- }
-
- switch val.Name() {
- case "NullInt64":
- return "bigint"
- case "NullFloat64":
- return "double precision"
- case "NullBool":
- return "boolean"
- case "NullTime", "Time":
- return "timestamp with time zone"
- }
-
- if maxsize > 0 {
- return fmt.Sprintf("varchar(%d)", maxsize)
- } else {
- return "text"
- }
-
-}
-
-// Returns empty string
-func (d OracleDialect) AutoIncrStr() string {
- return ""
-}
-
-func (d OracleDialect) AutoIncrBindValue() string {
- return "NULL"
-}
-
-func (d OracleDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
- return ""
-}
-
-// Returns suffix
-func (d OracleDialect) CreateTableSuffix() string {
- return ""
-}
-
-func (d OracleDialect) TruncateClause() string {
- return "truncate"
-}
-
-// Returns "$(i+1)"
-func (d OracleDialect) BindVar(i int) string {
- return fmt.Sprintf(":%d", i+1)
-}
-
-// After executing the insert uses the ColMap IdQuery to get the generated id
-func (d OracleDialect) InsertQueryToTarget(exec SqlExecutor, insertSql, idSql string, target interface{}, params ...interface{}) error {
- _, err := exec.Exec(insertSql, params...)
- if err != nil {
- return err
- }
- id, err := exec.SelectInt(idSql)
- if err != nil {
- return err
- }
- switch target.(type) {
- case *int64:
- *(target.(*int64)) = id
- case *int32:
- *(target.(*int32)) = int32(id)
- case int:
- *(target.(*int)) = int(id)
- default:
- return fmt.Errorf("Id field can be int, int32 or int64")
- }
- return nil
-}
-
-func (d OracleDialect) QuoteField(f string) string {
- return `"` + strings.ToUpper(f) + `"`
-}
-
-func (d OracleDialect) QuotedTableForQuery(schema string, table string) string {
- if strings.TrimSpace(schema) == "" {
- return d.QuoteField(table)
- }
-
- return schema + "." + d.QuoteField(table)
-}
-
-func (d OracleDialect) IfSchemaNotExists(command, schema string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
-
-func (d OracleDialect) IfTableExists(command, schema, table string) string {
- return fmt.Sprintf("%s if exists", command)
-}
-
-func (d OracleDialect) IfTableNotExists(command, schema, table string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_postgres.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_postgres.go
deleted file mode 100644
index a086381a8..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_postgres.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-type PostgresDialect struct {
- suffix string
-}
-
-func (d PostgresDialect) QuerySuffix() string { return ";" }
-
-func (d PostgresDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
- switch val.Kind() {
- case reflect.Ptr:
- return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
- case reflect.Bool:
- return "boolean"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
- if isAutoIncr {
- return "serial"
- }
- return "integer"
- case reflect.Int64, reflect.Uint64:
- if isAutoIncr {
- return "bigserial"
- }
- return "bigint"
- case reflect.Float64:
- return "double precision"
- case reflect.Float32:
- return "real"
- case reflect.Slice:
- if val.Elem().Kind() == reflect.Uint8 {
- return "bytea"
- }
- }
-
- switch val.Name() {
- case "NullInt64":
- return "bigint"
- case "NullFloat64":
- return "double precision"
- case "NullBool":
- return "boolean"
- case "Time", "NullTime":
- return "timestamp with time zone"
- }
-
- if maxsize > 0 {
- return fmt.Sprintf("varchar(%d)", maxsize)
- } else {
- return "text"
- }
-
-}
-
-// Returns empty string
-func (d PostgresDialect) AutoIncrStr() string {
- return ""
-}
-
-func (d PostgresDialect) AutoIncrBindValue() string {
- return "default"
-}
-
-func (d PostgresDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
- return " returning " + col.ColumnName
-}
-
-// Returns suffix
-func (d PostgresDialect) CreateTableSuffix() string {
- return d.suffix
-}
-
-func (d PostgresDialect) CreateIndexSuffix() string {
- return "using"
-}
-
-func (d PostgresDialect) DropIndexSuffix() string {
- return ""
-}
-
-func (d PostgresDialect) TruncateClause() string {
- return "truncate"
-}
-
-// Returns "$(i+1)"
-func (d PostgresDialect) BindVar(i int) string {
- return fmt.Sprintf("$%d", i+1)
-}
-
-func (d PostgresDialect) InsertAutoIncrToTarget(exec SqlExecutor, insertSql string, target interface{}, params ...interface{}) error {
- rows, err := exec.query(insertSql, params...)
- if err != nil {
- return err
- }
- defer rows.Close()
-
- if !rows.Next() {
- return fmt.Errorf("No serial value returned for insert: %s Encountered error: %s", insertSql, rows.Err())
- }
- if err := rows.Scan(target); err != nil {
- return err
- }
- if rows.Next() {
- return fmt.Errorf("more than two serial value returned for insert: %s", insertSql)
- }
- return rows.Err()
-}
-
-func (d PostgresDialect) QuoteField(f string) string {
- return `"` + strings.ToLower(f) + `"`
-}
-
-func (d PostgresDialect) QuotedTableForQuery(schema string, table string) string {
- if strings.TrimSpace(schema) == "" {
- return d.QuoteField(table)
- }
-
- return schema + "." + d.QuoteField(table)
-}
-
-func (d PostgresDialect) IfSchemaNotExists(command, schema string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
-
-func (d PostgresDialect) IfTableExists(command, schema, table string) string {
- return fmt.Sprintf("%s if exists", command)
-}
-
-func (d PostgresDialect) IfTableNotExists(command, schema, table string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlite.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlite.go
deleted file mode 100644
index 7d9b29757..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlite.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
-)
-
-type SqliteDialect struct {
- suffix string
-}
-
-func (d SqliteDialect) QuerySuffix() string { return ";" }
-
-func (d SqliteDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
- switch val.Kind() {
- case reflect.Ptr:
- return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
- case reflect.Bool:
- return "integer"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return "integer"
- case reflect.Float64, reflect.Float32:
- return "real"
- case reflect.Slice:
- if val.Elem().Kind() == reflect.Uint8 {
- return "blob"
- }
- }
-
- switch val.Name() {
- case "NullInt64":
- return "integer"
- case "NullFloat64":
- return "real"
- case "NullBool":
- return "integer"
- case "Time":
- return "datetime"
- }
-
- if maxsize < 1 {
- maxsize = 255
- }
- return fmt.Sprintf("varchar(%d)", maxsize)
-}
-
-// Returns autoincrement
-func (d SqliteDialect) AutoIncrStr() string {
- return "autoincrement"
-}
-
-func (d SqliteDialect) AutoIncrBindValue() string {
- return "null"
-}
-
-func (d SqliteDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
- return ""
-}
-
-// Returns suffix
-func (d SqliteDialect) CreateTableSuffix() string {
- return d.suffix
-}
-
-func (d SqliteDialect) CreateIndexSuffix() string {
- return ""
-}
-
-func (d SqliteDialect) DropIndexSuffix() string {
- return ""
-}
-
-// With sqlite, there technically isn't a TRUNCATE statement,
-// but a DELETE FROM uses a truncate optimization:
-// http://www.sqlite.org/lang_delete.html
-func (d SqliteDialect) TruncateClause() string {
- return "delete from"
-}
-
-// Returns "?"
-func (d SqliteDialect) BindVar(i int) string {
- return "?"
-}
-
-func (d SqliteDialect) InsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error) {
- return standardInsertAutoIncr(exec, insertSql, params...)
-}
-
-func (d SqliteDialect) QuoteField(f string) string {
- return `"` + f + `"`
-}
-
-// sqlite does not have schemas like PostgreSQL does, so just escape it like normal
-func (d SqliteDialect) QuotedTableForQuery(schema string, table string) string {
- return d.QuoteField(table)
-}
-
-func (d SqliteDialect) IfSchemaNotExists(command, schema string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
-
-func (d SqliteDialect) IfTableExists(command, schema, table string) string {
- return fmt.Sprintf("%s if exists", command)
-}
-
-func (d SqliteDialect) IfTableNotExists(command, schema, table string) string {
- return fmt.Sprintf("%s if not exists", command)
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlserver.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlserver.go
deleted file mode 100644
index 8808af598..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/dialect_sqlserver.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-// Implementation of Dialect for Microsoft SQL Server databases.
-// Use gorp.SqlServerDialect{"2005"} for legacy datatypes.
-// Tested with driver: github.com/denisenkom/go-mssqldb
-
-type SqlServerDialect struct {
-
- // If set to "2005" legacy datatypes will be used
- Version string
-}
-
-func (d SqlServerDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
- switch val.Kind() {
- case reflect.Ptr:
- return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
- case reflect.Bool:
- return "bit"
- case reflect.Int8:
- return "tinyint"
- case reflect.Uint8:
- return "smallint"
- case reflect.Int16:
- return "smallint"
- case reflect.Uint16:
- return "int"
- case reflect.Int, reflect.Int32:
- return "int"
- case reflect.Uint, reflect.Uint32:
- return "bigint"
- case reflect.Int64:
- return "bigint"
- case reflect.Uint64:
- return "numeric(20,0)"
- case reflect.Float32:
- return "float(24)"
- case reflect.Float64:
- return "float(53)"
- case reflect.Slice:
- if val.Elem().Kind() == reflect.Uint8 {
- return "varbinary"
- }
- }
-
- switch val.Name() {
- case "NullInt64":
- return "bigint"
- case "NullFloat64":
- return "float(53)"
- case "NullBool":
- return "bit"
- case "NullTime", "Time":
- if d.Version == "2005" {
- return "datetime"
- }
- return "datetime2"
- }
-
- if maxsize < 1 {
- if d.Version == "2005" {
- maxsize = 255
- } else {
- return fmt.Sprintf("nvarchar(max)")
- }
- }
- return fmt.Sprintf("nvarchar(%d)", maxsize)
-}
-
-// Returns auto_increment
-func (d SqlServerDialect) AutoIncrStr() string {
- return "identity(0,1)"
-}
-
-// Empty string removes autoincrement columns from the INSERT statements.
-func (d SqlServerDialect) AutoIncrBindValue() string {
- return ""
-}
-
-func (d SqlServerDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
- return ""
-}
-
-func (d SqlServerDialect) CreateTableSuffix() string { return ";" }
-
-func (d SqlServerDialect) TruncateClause() string {
- return "truncate table"
-}
-
-// Returns "?"
-func (d SqlServerDialect) BindVar(i int) string {
- return "?"
-}
-
-func (d SqlServerDialect) InsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error) {
- return standardInsertAutoIncr(exec, insertSql, params...)
-}
-
-func (d SqlServerDialect) QuoteField(f string) string {
- return "[" + strings.Replace(f, "]", "]]", -1) + "]"
-}
-
-func (d SqlServerDialect) QuotedTableForQuery(schema string, table string) string {
- if strings.TrimSpace(schema) == "" {
- return d.QuoteField(table)
- }
- return d.QuoteField(schema) + "." + d.QuoteField(table)
-}
-
-func (d SqlServerDialect) QuerySuffix() string { return ";" }
-
-func (d SqlServerDialect) IfSchemaNotExists(command, schema string) string {
- s := fmt.Sprintf("if schema_id(N'%s') is null %s", schema, command)
- return s
-}
-
-func (d SqlServerDialect) IfTableExists(command, schema, table string) string {
- var schema_clause string
- if strings.TrimSpace(schema) != "" {
- schema_clause = fmt.Sprintf("%s.", d.QuoteField(schema))
- }
- s := fmt.Sprintf("if object_id('%s%s') is not null %s", schema_clause, d.QuoteField(table), command)
- return s
-}
-
-func (d SqlServerDialect) IfTableNotExists(command, schema, table string) string {
- var schema_clause string
- if strings.TrimSpace(schema) != "" {
- schema_clause = fmt.Sprintf("%s.", schema)
- }
- s := fmt.Sprintf("if object_id('%s%s') is null %s", schema_clause, table, command)
- return s
-}
-
-func (d SqlServerDialect) CreateIndexSuffix() string { return "" }
-func (d SqlServerDialect) DropIndexSuffix() string { return "" }
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/errors.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/errors.go
deleted file mode 100644
index d13f03fc3..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/errors.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
-)
-
-// A non-fatal error, when a select query returns columns that do not exist
-// as fields in the struct it is being mapped to
-// TODO: discuss wether this needs an error. encoding/json silently ignores missing fields
-type NoFieldInTypeError struct {
- TypeName string
- MissingColNames []string
-}
-
-func (err *NoFieldInTypeError) Error() string {
- return fmt.Sprintf("gorp: no fields %+v in type %s", err.MissingColNames, err.TypeName)
-}
-
-// returns true if the error is non-fatal (ie, we shouldn't immediately return)
-func NonFatalError(err error) bool {
- switch err.(type) {
- case *NoFieldInTypeError:
- return true
- default:
- return false
- }
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/gorp.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/gorp.go
deleted file mode 100644
index 1f32283f5..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/gorp.go
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-//
-package gorp
-
-import (
- "database/sql"
- "database/sql/driver"
- "fmt"
- "reflect"
- "regexp"
- "strings"
- "time"
-)
-
-// OracleString (empty string is null)
-// TODO: move to dialect/oracle?, rename to String?
-type OracleString struct {
- sql.NullString
-}
-
-// Scan implements the Scanner interface.
-func (os *OracleString) Scan(value interface{}) error {
- if value == nil {
- os.String, os.Valid = "", false
- return nil
- }
- os.Valid = true
- return os.NullString.Scan(value)
-}
-
-// Value implements the driver Valuer interface.
-func (os OracleString) Value() (driver.Value, error) {
- if !os.Valid || os.String == "" {
- return nil, nil
- }
- return os.String, nil
-}
-
-// SqlTyper is a type that returns its database type. Most of the
-// time, the type can just use "database/sql/driver".Valuer; but when
-// it returns nil for its empty value, it needs to implement SqlTyper
-// to have its column type detected properly during table creation.
-type SqlTyper interface {
- SqlType() driver.Valuer
-}
-
-// for fields that exists in DB table, but not exists in struct
-type dummyField struct{}
-
-// Scan implements the Scanner interface.
-func (nt *dummyField) Scan(value interface{}) error {
- return nil
-}
-
-var zeroVal reflect.Value
-var versFieldConst = "[gorp_ver_field]"
-
-// The TypeConverter interface provides a way to map a value of one
-// type to another type when persisting to, or loading from, a database.
-//
-// Example use cases: Implement type converter to convert bool types to "y"/"n" strings,
-// or serialize a struct member as a JSON blob.
-type TypeConverter interface {
- // ToDb converts val to another type. Called before INSERT/UPDATE operations
- ToDb(val interface{}) (interface{}, error)
-
- // FromDb returns a CustomScanner appropriate for this type. This will be used
- // to hold values returned from SELECT queries.
- //
- // In particular the CustomScanner returned should implement a Binder
- // function appropriate for the Go type you wish to convert the db value to
- //
- // If bool==false, then no custom scanner will be used for this field.
- FromDb(target interface{}) (CustomScanner, bool)
-}
-
-// Executor exposes the sql.DB and sql.Tx Exec function so that it can be used
-// on internal functions that convert named parameters for the Exec function.
-type executor interface {
- Exec(query string, args ...interface{}) (sql.Result, error)
-}
-
-// SqlExecutor exposes gorp operations that can be run from Pre/Post
-// hooks. This hides whether the current operation that triggered the
-// hook is in a transaction.
-//
-// See the DbMap function docs for each of the functions below for more
-// information.
-type SqlExecutor interface {
- Get(i interface{}, keys ...interface{}) (interface{}, error)
- Insert(list ...interface{}) error
- Update(list ...interface{}) (int64, error)
- Delete(list ...interface{}) (int64, error)
- Exec(query string, args ...interface{}) (sql.Result, error)
- Select(i interface{}, query string,
- args ...interface{}) ([]interface{}, error)
- SelectInt(query string, args ...interface{}) (int64, error)
- SelectNullInt(query string, args ...interface{}) (sql.NullInt64, error)
- SelectFloat(query string, args ...interface{}) (float64, error)
- SelectNullFloat(query string, args ...interface{}) (sql.NullFloat64, error)
- SelectStr(query string, args ...interface{}) (string, error)
- SelectNullStr(query string, args ...interface{}) (sql.NullString, error)
- SelectOne(holder interface{}, query string, args ...interface{}) error
- query(query string, args ...interface{}) (*sql.Rows, error)
- queryRow(query string, args ...interface{}) *sql.Row
-}
-
-// Compile-time check that DbMap and Transaction implement the SqlExecutor
-// interface.
-var _, _ SqlExecutor = &DbMap{}, &Transaction{}
-
-func argsString(args ...interface{}) string {
- var margs string
- for i, a := range args {
- var v interface{} = a
- if x, ok := v.(driver.Valuer); ok {
- y, err := x.Value()
- if err == nil {
- v = y
- }
- }
- switch v.(type) {
- case string:
- v = fmt.Sprintf("%q", v)
- default:
- v = fmt.Sprintf("%v", v)
- }
- margs += fmt.Sprintf("%d:%s", i+1, v)
- if i+1 < len(args) {
- margs += " "
- }
- }
- return margs
-}
-
-// Calls the Exec function on the executor, but attempts to expand any eligible named
-// query arguments first.
-func exec(e SqlExecutor, query string, args ...interface{}) (sql.Result, error) {
- var dbMap *DbMap
- var executor executor
- switch m := e.(type) {
- case *DbMap:
- executor = m.Db
- dbMap = m
- case *Transaction:
- executor = m.tx
- dbMap = m.dbmap
- }
-
- if len(args) == 1 {
- query, args = maybeExpandNamedQuery(dbMap, query, args)
- }
-
- return executor.Exec(query, args...)
-}
-
-// maybeExpandNamedQuery checks the given arg to see if it's eligible to be used
-// as input to a named query. If so, it rewrites the query to use
-// dialect-dependent bindvars and instantiates the corresponding slice of
-// parameters by extracting data from the map / struct.
-// If not, returns the input values unchanged.
-func maybeExpandNamedQuery(m *DbMap, query string, args []interface{}) (string, []interface{}) {
- var (
- arg = args[0]
- argval = reflect.ValueOf(arg)
- )
- if argval.Kind() == reflect.Ptr {
- argval = argval.Elem()
- }
-
- if argval.Kind() == reflect.Map && argval.Type().Key().Kind() == reflect.String {
- return expandNamedQuery(m, query, func(key string) reflect.Value {
- return argval.MapIndex(reflect.ValueOf(key))
- })
- }
- if argval.Kind() != reflect.Struct {
- return query, args
- }
- if _, ok := arg.(time.Time); ok {
- // time.Time is driver.Value
- return query, args
- }
- if _, ok := arg.(driver.Valuer); ok {
- // driver.Valuer will be converted to driver.Value.
- return query, args
- }
-
- return expandNamedQuery(m, query, argval.FieldByName)
-}
-
-var keyRegexp = regexp.MustCompile(`:[[:word:]]+`)
-
-// expandNamedQuery accepts a query with placeholders of the form ":key", and a
-// single arg of Kind Struct or Map[string]. It returns the query with the
-// dialect's placeholders, and a slice of args ready for positional insertion
-// into the query.
-func expandNamedQuery(m *DbMap, query string, keyGetter func(key string) reflect.Value) (string, []interface{}) {
- var (
- n int
- args []interface{}
- )
- return keyRegexp.ReplaceAllStringFunc(query, func(key string) string {
- val := keyGetter(key[1:])
- if !val.IsValid() {
- return key
- }
- args = append(args, val.Interface())
- newVar := m.Dialect.BindVar(n)
- n++
- return newVar
- }), args
-}
-
-func columnToFieldIndex(m *DbMap, t reflect.Type, cols []string) ([][]int, error) {
- colToFieldIndex := make([][]int, len(cols))
-
- // check if type t is a mapped table - if so we'll
- // check the table for column aliasing below
- tableMapped := false
- table := tableOrNil(m, t)
- if table != nil {
- tableMapped = true
- }
-
- // Loop over column names and find field in i to bind to
- // based on column name. all returned columns must match
- // a field in the i struct
- missingColNames := []string{}
- for x := range cols {
- colName := strings.ToLower(cols[x])
- field, found := t.FieldByNameFunc(func(fieldName string) bool {
- field, _ := t.FieldByName(fieldName)
- cArguments := strings.Split(field.Tag.Get("db"), ",")
- fieldName = cArguments[0]
-
- if fieldName == "-" {
- return false
- } else if fieldName == "" {
- fieldName = field.Name
- }
- if tableMapped {
- colMap := colMapOrNil(table, fieldName)
- if colMap != nil {
- fieldName = colMap.ColumnName
- }
- }
- return colName == strings.ToLower(fieldName)
- })
- if found {
- colToFieldIndex[x] = field.Index
- }
- if colToFieldIndex[x] == nil {
- missingColNames = append(missingColNames, colName)
- }
- }
- if len(missingColNames) > 0 {
- return colToFieldIndex, &NoFieldInTypeError{
- TypeName: t.Name(),
- MissingColNames: missingColNames,
- }
- }
- return colToFieldIndex, nil
-}
-
-func fieldByName(val reflect.Value, fieldName string) *reflect.Value {
- // try to find field by exact match
- f := val.FieldByName(fieldName)
-
- if f != zeroVal {
- return &f
- }
-
- // try to find by case insensitive match - only the Postgres driver
- // seems to require this - in the case where columns are aliased in the sql
- fieldNameL := strings.ToLower(fieldName)
- fieldCount := val.NumField()
- t := val.Type()
- for i := 0; i < fieldCount; i++ {
- sf := t.Field(i)
- if strings.ToLower(sf.Name) == fieldNameL {
- f := val.Field(i)
- return &f
- }
- }
-
- return nil
-}
-
-// toSliceType returns the element type of the given object, if the object is a
-// "*[]*Element" or "*[]Element". If not, returns nil.
-// err is returned if the user was trying to pass a pointer-to-slice but failed.
-func toSliceType(i interface{}) (reflect.Type, error) {
- t := reflect.TypeOf(i)
- if t.Kind() != reflect.Ptr {
- // If it's a slice, return a more helpful error message
- if t.Kind() == reflect.Slice {
- return nil, fmt.Errorf("gorp: cannot SELECT into a non-pointer slice: %v", t)
- }
- return nil, nil
- }
- if t = t.Elem(); t.Kind() != reflect.Slice {
- return nil, nil
- }
- return t.Elem(), nil
-}
-
-func toType(i interface{}) (reflect.Type, error) {
- t := reflect.TypeOf(i)
-
- // If a Pointer to a type, follow
- for t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
-
- if t.Kind() != reflect.Struct {
- return nil, fmt.Errorf("gorp: cannot SELECT into this type: %v", reflect.TypeOf(i))
- }
- return t, nil
-}
-
-func get(m *DbMap, exec SqlExecutor, i interface{},
- keys ...interface{}) (interface{}, error) {
-
- t, err := toType(i)
- if err != nil {
- return nil, err
- }
-
- table, err := m.TableFor(t, true)
- if err != nil {
- return nil, err
- }
-
- plan := table.bindGet()
-
- v := reflect.New(t)
- dest := make([]interface{}, len(plan.argFields))
-
- conv := m.TypeConverter
- custScan := make([]CustomScanner, 0)
-
- for x, fieldName := range plan.argFields {
- f := v.Elem().FieldByName(fieldName)
- target := f.Addr().Interface()
- if conv != nil {
- scanner, ok := conv.FromDb(target)
- if ok {
- target = scanner.Holder
- custScan = append(custScan, scanner)
- }
- }
- dest[x] = target
- }
-
- row := exec.queryRow(plan.query, keys...)
- err = row.Scan(dest...)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return nil, err
- }
-
- for _, c := range custScan {
- err = c.Bind()
- if err != nil {
- return nil, err
- }
- }
-
- if v, ok := v.Interface().(HasPostGet); ok {
- err := v.PostGet(exec)
- if err != nil {
- return nil, err
- }
- }
-
- return v.Interface(), nil
-}
-
-func delete(m *DbMap, exec SqlExecutor, list ...interface{}) (int64, error) {
- count := int64(0)
- for _, ptr := range list {
- table, elem, err := m.tableForPointer(ptr, true)
- if err != nil {
- return -1, err
- }
-
- eval := elem.Addr().Interface()
- if v, ok := eval.(HasPreDelete); ok {
- err = v.PreDelete(exec)
- if err != nil {
- return -1, err
- }
- }
-
- bi, err := table.bindDelete(elem)
- if err != nil {
- return -1, err
- }
-
- res, err := exec.Exec(bi.query, bi.args...)
- if err != nil {
- return -1, err
- }
- rows, err := res.RowsAffected()
- if err != nil {
- return -1, err
- }
-
- if rows == 0 && bi.existingVersion > 0 {
- return lockError(m, exec, table.TableName,
- bi.existingVersion, elem, bi.keys...)
- }
-
- count += rows
-
- if v, ok := eval.(HasPostDelete); ok {
- err := v.PostDelete(exec)
- if err != nil {
- return -1, err
- }
- }
- }
-
- return count, nil
-}
-
-func update(m *DbMap, exec SqlExecutor, colFilter ColumnFilter, list ...interface{}) (int64, error) {
- count := int64(0)
- for _, ptr := range list {
- table, elem, err := m.tableForPointer(ptr, true)
- if err != nil {
- return -1, err
- }
-
- eval := elem.Addr().Interface()
- if v, ok := eval.(HasPreUpdate); ok {
- err = v.PreUpdate(exec)
- if err != nil {
- return -1, err
- }
- }
-
- bi, err := table.bindUpdate(elem, colFilter)
- if err != nil {
- return -1, err
- }
-
- res, err := exec.Exec(bi.query, bi.args...)
- if err != nil {
- return -1, err
- }
-
- rows, err := res.RowsAffected()
- if err != nil {
- return -1, err
- }
-
- if rows == 0 && bi.existingVersion > 0 {
- return lockError(m, exec, table.TableName,
- bi.existingVersion, elem, bi.keys...)
- }
-
- if bi.versField != "" {
- elem.FieldByName(bi.versField).SetInt(bi.existingVersion + 1)
- }
-
- count += rows
-
- if v, ok := eval.(HasPostUpdate); ok {
- err = v.PostUpdate(exec)
- if err != nil {
- return -1, err
- }
- }
- }
- return count, nil
-}
-
-func insert(m *DbMap, exec SqlExecutor, list ...interface{}) error {
- for _, ptr := range list {
- table, elem, err := m.tableForPointer(ptr, false)
- if err != nil {
- return err
- }
-
- eval := elem.Addr().Interface()
- if v, ok := eval.(HasPreInsert); ok {
- err := v.PreInsert(exec)
- if err != nil {
- return err
- }
- }
-
- bi, err := table.bindInsert(elem)
- if err != nil {
- return err
- }
-
- if bi.autoIncrIdx > -1 {
- f := elem.FieldByName(bi.autoIncrFieldName)
- switch inserter := m.Dialect.(type) {
- case IntegerAutoIncrInserter:
- id, err := inserter.InsertAutoIncr(exec, bi.query, bi.args...)
- if err != nil {
- return err
- }
- k := f.Kind()
- if (k == reflect.Int) || (k == reflect.Int16) || (k == reflect.Int32) || (k == reflect.Int64) {
- f.SetInt(id)
- } else if (k == reflect.Uint) || (k == reflect.Uint16) || (k == reflect.Uint32) || (k == reflect.Uint64) {
- f.SetUint(uint64(id))
- } else {
- return fmt.Errorf("gorp: cannot set autoincrement value on non-Int field. SQL=%s autoIncrIdx=%d autoIncrFieldName=%s", bi.query, bi.autoIncrIdx, bi.autoIncrFieldName)
- }
- case TargetedAutoIncrInserter:
- err := inserter.InsertAutoIncrToTarget(exec, bi.query, f.Addr().Interface(), bi.args...)
- if err != nil {
- return err
- }
- case TargetQueryInserter:
- var idQuery = table.ColMap(bi.autoIncrFieldName).GeneratedIdQuery
- if idQuery == "" {
- return fmt.Errorf("gorp: cannot set %s value if its ColumnMap.GeneratedIdQuery is empty", bi.autoIncrFieldName)
- }
- err := inserter.InsertQueryToTarget(exec, bi.query, idQuery, f.Addr().Interface(), bi.args...)
- if err != nil {
- return err
- }
- default:
- return fmt.Errorf("gorp: cannot use autoincrement fields on dialects that do not implement an autoincrementing interface")
- }
- } else {
- _, err := exec.Exec(bi.query, bi.args...)
- if err != nil {
- return err
- }
- }
-
- if v, ok := eval.(HasPostInsert); ok {
- err := v.PostInsert(exec)
- if err != nil {
- return err
- }
- }
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/hooks.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/hooks.go
deleted file mode 100644
index 192b51f00..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/hooks.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-//++ TODO v2-phase3: HasPostGet => PostGetter, HasPostDelete => PostDeleter, etc.
-
-// PostUpdate() will be executed after the GET statement.
-type HasPostGet interface {
- PostGet(SqlExecutor) error
-}
-
-// PostUpdate() will be executed after the DELETE statement
-type HasPostDelete interface {
- PostDelete(SqlExecutor) error
-}
-
-// PostUpdate() will be executed after the UPDATE statement
-type HasPostUpdate interface {
- PostUpdate(SqlExecutor) error
-}
-
-// PostInsert() will be executed after the INSERT statement
-type HasPostInsert interface {
- PostInsert(SqlExecutor) error
-}
-
-// PreDelete() will be executed before the DELETE statement.
-type HasPreDelete interface {
- PreDelete(SqlExecutor) error
-}
-
-// PreUpdate() will be executed before UPDATE statement.
-type HasPreUpdate interface {
- PreUpdate(SqlExecutor) error
-}
-
-// PreInsert() will be executed before INSERT statement.
-type HasPreInsert interface {
- PreInsert(SqlExecutor) error
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/index.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/index.go
deleted file mode 100644
index 01ecd9eca..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/index.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-// IndexMap represents a mapping between a Go struct field and a single
-// index in a table.
-// Unique and MaxSize only inform the
-// CreateTables() function and are not used by Insert/Update/Delete/Get.
-type IndexMap struct {
- // Index name in db table
- IndexName string
-
- // If true, " unique" is added to create index statements.
- // Not used elsewhere
- Unique bool
-
- // Index type supported by Dialect
- // Postgres: B-tree, Hash, GiST and GIN.
- // Mysql: Btree, Hash.
- // Sqlite: nil.
- IndexType string
-
- // Columns name for single and multiple indexes
- columns []string
-}
-
-// Rename allows you to specify the index name in the table
-//
-// Example: table.IndMap("customer_test_idx").Rename("customer_idx")
-//
-func (idx *IndexMap) Rename(indname string) *IndexMap {
- idx.IndexName = indname
- return idx
-}
-
-// SetUnique adds "unique" to the create index statements for this
-// index, if b is true.
-func (idx *IndexMap) SetUnique(b bool) *IndexMap {
- idx.Unique = b
- return idx
-}
-
-// SetIndexType specifies the index type supported by chousen SQL Dialect
-func (idx *IndexMap) SetIndexType(indtype string) *IndexMap {
- idx.IndexType = indtype
- return idx
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/lockerror.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/lockerror.go
deleted file mode 100644
index 07b3047ae..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/lockerror.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "fmt"
- "reflect"
-)
-
-// OptimisticLockError is returned by Update() or Delete() if the
-// struct being modified has a Version field and the value is not equal to
-// the current value in the database
-type OptimisticLockError struct {
- // Table name where the lock error occurred
- TableName string
-
- // Primary key values of the row being updated/deleted
- Keys []interface{}
-
- // true if a row was found with those keys, indicating the
- // LocalVersion is stale. false if no value was found with those
- // keys, suggesting the row has been deleted since loaded, or
- // was never inserted to begin with
- RowExists bool
-
- // Version value on the struct passed to Update/Delete. This value is
- // out of sync with the database.
- LocalVersion int64
-}
-
-// Error returns a description of the cause of the lock error
-func (e OptimisticLockError) Error() string {
- if e.RowExists {
- return fmt.Sprintf("gorp: OptimisticLockError table=%s keys=%v out of date version=%d", e.TableName, e.Keys, e.LocalVersion)
- }
-
- return fmt.Sprintf("gorp: OptimisticLockError no row found for table=%s keys=%v", e.TableName, e.Keys)
-}
-
-func lockError(m *DbMap, exec SqlExecutor, tableName string,
- existingVer int64, elem reflect.Value,
- keys ...interface{}) (int64, error) {
-
- existing, err := get(m, exec, elem.Interface(), keys...)
- if err != nil {
- return -1, err
- }
-
- ole := OptimisticLockError{tableName, keys, true, existingVer}
- if existing == nil {
- ole.RowExists = false
- }
- return -1, ole
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/logging.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/logging.go
deleted file mode 100644
index 89d6c0e79..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/logging.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import "fmt"
-
-type GorpLogger interface {
- Printf(format string, v ...interface{})
-}
-
-// TraceOn turns on SQL statement logging for this DbMap. After this is
-// called, all SQL statements will be sent to the logger. If prefix is
-// a non-empty string, it will be written to the front of all logged
-// strings, which can aid in filtering log lines.
-//
-// Use TraceOn if you want to spy on the SQL statements that gorp
-// generates.
-//
-// Note that the base log.Logger type satisfies GorpLogger, but adapters can
-// easily be written for other logging packages (e.g., the golang-sanctioned
-// glog framework).
-func (m *DbMap) TraceOn(prefix string, logger GorpLogger) {
- m.logger = logger
- if prefix == "" {
- m.logPrefix = prefix
- } else {
- m.logPrefix = fmt.Sprintf("%s ", prefix)
- }
-}
-
-// TraceOff turns off tracing. It is idempotent.
-func (m *DbMap) TraceOff() {
- m.logger = nil
- m.logPrefix = ""
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/nulltypes.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/nulltypes.go
deleted file mode 100644
index 870770372..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/nulltypes.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "database/sql/driver"
- "time"
-)
-
-// A nullable Time value
-type NullTime struct {
- Time time.Time
- Valid bool // Valid is true if Time is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (nt *NullTime) Scan(value interface{}) error {
- switch t := value.(type) {
- case time.Time:
- nt.Time, nt.Valid = t, true
- case []byte:
- nt.Valid = false
- for _, dtfmt := range []string{
- "2006-01-02 15:04:05.999999999",
- "2006-01-02T15:04:05.999999999",
- "2006-01-02 15:04:05",
- "2006-01-02T15:04:05",
- "2006-01-02 15:04",
- "2006-01-02T15:04",
- "2006-01-02",
- "2006-01-02 15:04:05-07:00",
- } {
- var err error
- if nt.Time, err = time.Parse(dtfmt, string(t)); err == nil {
- nt.Valid = true
- break
- }
- }
- }
- return nil
-}
-
-// Value implements the driver Valuer interface.
-func (nt NullTime) Value() (driver.Value, error) {
- if !nt.Valid {
- return nil, nil
- }
- return nt.Time, nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/select.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/select.go
deleted file mode 100644
index d6ff92ee3..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/select.go
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "database/sql"
- "fmt"
- "reflect"
-)
-
-// SelectInt executes the given query, which should be a SELECT statement for a single
-// integer column, and returns the value of the first row returned. If no rows are
-// found, zero is returned.
-func SelectInt(e SqlExecutor, query string, args ...interface{}) (int64, error) {
- var h int64
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return 0, err
- }
- return h, nil
-}
-
-// SelectNullInt executes the given query, which should be a SELECT statement for a single
-// integer column, and returns the value of the first row returned. If no rows are
-// found, the empty sql.NullInt64 value is returned.
-func SelectNullInt(e SqlExecutor, query string, args ...interface{}) (sql.NullInt64, error) {
- var h sql.NullInt64
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return h, err
- }
- return h, nil
-}
-
-// SelectFloat executes the given query, which should be a SELECT statement for a single
-// float column, and returns the value of the first row returned. If no rows are
-// found, zero is returned.
-func SelectFloat(e SqlExecutor, query string, args ...interface{}) (float64, error) {
- var h float64
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return 0, err
- }
- return h, nil
-}
-
-// SelectNullFloat executes the given query, which should be a SELECT statement for a single
-// float column, and returns the value of the first row returned. If no rows are
-// found, the empty sql.NullInt64 value is returned.
-func SelectNullFloat(e SqlExecutor, query string, args ...interface{}) (sql.NullFloat64, error) {
- var h sql.NullFloat64
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return h, err
- }
- return h, nil
-}
-
-// SelectStr executes the given query, which should be a SELECT statement for a single
-// char/varchar column, and returns the value of the first row returned. If no rows are
-// found, an empty string is returned.
-func SelectStr(e SqlExecutor, query string, args ...interface{}) (string, error) {
- var h string
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return "", err
- }
- return h, nil
-}
-
-// SelectNullStr executes the given query, which should be a SELECT
-// statement for a single char/varchar column, and returns the value
-// of the first row returned. If no rows are found, the empty
-// sql.NullString is returned.
-func SelectNullStr(e SqlExecutor, query string, args ...interface{}) (sql.NullString, error) {
- var h sql.NullString
- err := selectVal(e, &h, query, args...)
- if err != nil && err != sql.ErrNoRows {
- return h, err
- }
- return h, nil
-}
-
-// SelectOne executes the given query (which should be a SELECT statement)
-// and binds the result to holder, which must be a pointer.
-//
-// If no row is found, an error (sql.ErrNoRows specifically) will be returned
-//
-// If more than one row is found, an error will be returned.
-//
-func SelectOne(m *DbMap, e SqlExecutor, holder interface{}, query string, args ...interface{}) error {
- t := reflect.TypeOf(holder)
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- } else {
- return fmt.Errorf("gorp: SelectOne holder must be a pointer, but got: %t", holder)
- }
-
- // Handle pointer to pointer
- isptr := false
- if t.Kind() == reflect.Ptr {
- isptr = true
- t = t.Elem()
- }
-
- if t.Kind() == reflect.Struct {
- var nonFatalErr error
-
- list, err := hookedselect(m, e, holder, query, args...)
- if err != nil {
- if !NonFatalError(err) { // FIXME: double negative, rename NonFatalError to FatalError
- return err
- }
- nonFatalErr = err
- }
-
- dest := reflect.ValueOf(holder)
- if isptr {
- dest = dest.Elem()
- }
-
- if list != nil && len(list) > 0 { // FIXME: invert if/else
- // check for multiple rows
- if len(list) > 1 {
- return fmt.Errorf("gorp: multiple rows returned for: %s - %v", query, args)
- }
-
- // Initialize if nil
- if dest.IsNil() {
- dest.Set(reflect.New(t))
- }
-
- // only one row found
- src := reflect.ValueOf(list[0])
- dest.Elem().Set(src.Elem())
- } else {
- // No rows found, return a proper error.
- return sql.ErrNoRows
- }
-
- return nonFatalErr
- }
-
- return selectVal(e, holder, query, args...)
-}
-
-func selectVal(e SqlExecutor, holder interface{}, query string, args ...interface{}) error {
- if len(args) == 1 {
- switch m := e.(type) {
- case *DbMap:
- query, args = maybeExpandNamedQuery(m, query, args)
- case *Transaction:
- query, args = maybeExpandNamedQuery(m.dbmap, query, args)
- }
- }
- rows, err := e.query(query, args...)
- if err != nil {
- return err
- }
- defer rows.Close()
-
- if !rows.Next() {
- return sql.ErrNoRows
- }
-
- return rows.Scan(holder)
-}
-
-func hookedselect(m *DbMap, exec SqlExecutor, i interface{}, query string,
- args ...interface{}) ([]interface{}, error) {
-
- var nonFatalErr error
-
- list, err := rawselect(m, exec, i, query, args...)
- if err != nil {
- if !NonFatalError(err) {
- return nil, err
- }
- nonFatalErr = err
- }
-
- // Determine where the results are: written to i, or returned in list
- if t, _ := toSliceType(i); t == nil {
- for _, v := range list {
- if v, ok := v.(HasPostGet); ok {
- err := v.PostGet(exec)
- if err != nil {
- return nil, err
- }
- }
- }
- } else {
- resultsValue := reflect.Indirect(reflect.ValueOf(i))
- for i := 0; i < resultsValue.Len(); i++ {
- if v, ok := resultsValue.Index(i).Interface().(HasPostGet); ok {
- err := v.PostGet(exec)
- if err != nil {
- return nil, err
- }
- }
- }
- }
- return list, nonFatalErr
-}
-
-func rawselect(m *DbMap, exec SqlExecutor, i interface{}, query string,
- args ...interface{}) ([]interface{}, error) {
- var (
- appendToSlice = false // Write results to i directly?
- intoStruct = true // Selecting into a struct?
- pointerElements = true // Are the slice elements pointers (vs values)?
- )
-
- var nonFatalErr error
-
- // get type for i, verifying it's a supported destination
- t, err := toType(i)
- if err != nil {
- var err2 error
- if t, err2 = toSliceType(i); t == nil {
- if err2 != nil {
- return nil, err2
- }
- return nil, err
- }
- pointerElements = t.Kind() == reflect.Ptr
- if pointerElements {
- t = t.Elem()
- }
- appendToSlice = true
- intoStruct = t.Kind() == reflect.Struct
- }
-
- // If the caller supplied a single struct/map argument, assume a "named
- // parameter" query. Extract the named arguments from the struct/map, create
- // the flat arg slice, and rewrite the query to use the dialect's placeholder.
- if len(args) == 1 {
- query, args = maybeExpandNamedQuery(m, query, args)
- }
-
- // Run the query
- rows, err := exec.query(query, args...)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- // Fetch the column names as returned from db
- cols, err := rows.Columns()
- if err != nil {
- return nil, err
- }
-
- if !intoStruct && len(cols) > 1 {
- return nil, fmt.Errorf("gorp: select into non-struct slice requires 1 column, got %d", len(cols))
- }
-
- var colToFieldIndex [][]int
- if intoStruct {
- colToFieldIndex, err = columnToFieldIndex(m, t, cols)
- if err != nil {
- if !NonFatalError(err) {
- return nil, err
- }
- nonFatalErr = err
- }
- }
-
- conv := m.TypeConverter
-
- // Add results to one of these two slices.
- var (
- list = make([]interface{}, 0)
- sliceValue = reflect.Indirect(reflect.ValueOf(i))
- )
-
- for {
- if !rows.Next() {
- // if error occured return rawselect
- if rows.Err() != nil {
- return nil, rows.Err()
- }
- // time to exit from outer "for" loop
- break
- }
- v := reflect.New(t)
- dest := make([]interface{}, len(cols))
-
- custScan := make([]CustomScanner, 0)
-
- for x := range cols {
- f := v.Elem()
- if intoStruct {
- index := colToFieldIndex[x]
- if index == nil {
- // this field is not present in the struct, so create a dummy
- // value for rows.Scan to scan into
- var dummy dummyField
- dest[x] = &dummy
- continue
- }
- f = f.FieldByIndex(index)
- }
- target := f.Addr().Interface()
- if conv != nil {
- scanner, ok := conv.FromDb(target)
- if ok {
- target = scanner.Holder
- custScan = append(custScan, scanner)
- }
- }
- dest[x] = target
- }
-
- err = rows.Scan(dest...)
- if err != nil {
- return nil, err
- }
-
- for _, c := range custScan {
- err = c.Bind()
- if err != nil {
- return nil, err
- }
- }
-
- if appendToSlice {
- if !pointerElements {
- v = v.Elem()
- }
- sliceValue.Set(reflect.Append(sliceValue, v))
- } else {
- list = append(list, v.Interface())
- }
- }
-
- if appendToSlice && sliceValue.IsNil() {
- sliceValue.Set(reflect.MakeSlice(sliceValue.Type(), 0, 0))
- }
-
- return list, nonFatalErr
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/table.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/table.go
deleted file mode 100644
index 5c513909a..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/table.go
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "strings"
-)
-
-// TableMap represents a mapping between a Go struct and a database table
-// Use dbmap.AddTable() or dbmap.AddTableWithName() to create these
-type TableMap struct {
- // Name of database table.
- TableName string
- SchemaName string
- gotype reflect.Type
- Columns []*ColumnMap
- keys []*ColumnMap
- indexes []*IndexMap
- uniqueTogether [][]string
- version *ColumnMap
- insertPlan bindPlan
- updatePlan bindPlan
- deletePlan bindPlan
- getPlan bindPlan
- dbmap *DbMap
-}
-
-// ResetSql removes cached insert/update/select/delete SQL strings
-// associated with this TableMap. Call this if you've modified
-// any column names or the table name itself.
-func (t *TableMap) ResetSql() {
- t.insertPlan = bindPlan{}
- t.updatePlan = bindPlan{}
- t.deletePlan = bindPlan{}
- t.getPlan = bindPlan{}
-}
-
-// SetKeys lets you specify the fields on a struct that map to primary
-// key columns on the table. If isAutoIncr is set, result.LastInsertId()
-// will be used after INSERT to bind the generated id to the Go struct.
-//
-// Automatically calls ResetSql() to ensure SQL statements are regenerated.
-//
-// Panics if isAutoIncr is true, and fieldNames length != 1
-//
-func (t *TableMap) SetKeys(isAutoIncr bool, fieldNames ...string) *TableMap {
- if isAutoIncr && len(fieldNames) != 1 {
- panic(fmt.Sprintf(
- "gorp: SetKeys: fieldNames length must be 1 if key is auto-increment. (Saw %v fieldNames)",
- len(fieldNames)))
- }
- t.keys = make([]*ColumnMap, 0)
- for _, name := range fieldNames {
- colmap := t.ColMap(name)
- colmap.isPK = true
- colmap.isAutoIncr = isAutoIncr
- t.keys = append(t.keys, colmap)
- }
- t.ResetSql()
-
- return t
-}
-
-// SetUniqueTogether lets you specify uniqueness constraints across multiple
-// columns on the table. Each call adds an additional constraint for the
-// specified columns.
-//
-// Automatically calls ResetSql() to ensure SQL statements are regenerated.
-//
-// Panics if fieldNames length < 2.
-//
-func (t *TableMap) SetUniqueTogether(fieldNames ...string) *TableMap {
- if len(fieldNames) < 2 {
- panic(fmt.Sprintf(
- "gorp: SetUniqueTogether: must provide at least two fieldNames to set uniqueness constraint."))
- }
-
- columns := make([]string, 0)
- for _, name := range fieldNames {
- columns = append(columns, name)
- }
- t.uniqueTogether = append(t.uniqueTogether, columns)
- t.ResetSql()
-
- return t
-}
-
-// ColMap returns the ColumnMap pointer matching the given struct field
-// name. It panics if the struct does not contain a field matching this
-// name.
-func (t *TableMap) ColMap(field string) *ColumnMap {
- col := colMapOrNil(t, field)
- if col == nil {
- e := fmt.Sprintf("No ColumnMap in table %s type %s with field %s",
- t.TableName, t.gotype.Name(), field)
-
- panic(e)
- }
- return col
-}
-
-func colMapOrNil(t *TableMap, field string) *ColumnMap {
- for _, col := range t.Columns {
- if col.fieldName == field || col.ColumnName == field {
- return col
- }
- }
- return nil
-}
-
-// IdxMap returns the IndexMap pointer matching the given index name.
-func (t *TableMap) IdxMap(field string) *IndexMap {
- for _, idx := range t.indexes {
- if idx.IndexName == field {
- return idx
- }
- }
- return nil
-}
-
-// AddIndex registers the index with gorp for specified table with given parameters.
-// This operation is idempotent. If index is already mapped, the
-// existing *IndexMap is returned
-// Function will panic if one of the given for index columns does not exists
-//
-// Automatically calls ResetSql() to ensure SQL statements are regenerated.
-//
-func (t *TableMap) AddIndex(name string, idxtype string, columns []string) *IndexMap {
- // check if we have a index with this name already
- for _, idx := range t.indexes {
- if idx.IndexName == name {
- return idx
- }
- }
- for _, icol := range columns {
- if res := t.ColMap(icol); res == nil {
- e := fmt.Sprintf("No ColumnName in table %s to create index on", t.TableName)
- panic(e)
- }
- }
-
- idx := &IndexMap{IndexName: name, Unique: false, IndexType: idxtype, columns: columns}
- t.indexes = append(t.indexes, idx)
- t.ResetSql()
- return idx
-}
-
-// SetVersionCol sets the column to use as the Version field. By default
-// the "Version" field is used. Returns the column found, or panics
-// if the struct does not contain a field matching this name.
-//
-// Automatically calls ResetSql() to ensure SQL statements are regenerated.
-func (t *TableMap) SetVersionCol(field string) *ColumnMap {
- c := t.ColMap(field)
- t.version = c
- t.ResetSql()
- return c
-}
-
-// SqlForCreateTable gets a sequence of SQL commands that will create
-// the specified table and any associated schema
-func (t *TableMap) SqlForCreate(ifNotExists bool) string {
- s := bytes.Buffer{}
- dialect := t.dbmap.Dialect
-
- if strings.TrimSpace(t.SchemaName) != "" {
- schemaCreate := "create schema"
- if ifNotExists {
- s.WriteString(dialect.IfSchemaNotExists(schemaCreate, t.SchemaName))
- } else {
- s.WriteString(schemaCreate)
- }
- s.WriteString(fmt.Sprintf(" %s;", t.SchemaName))
- }
-
- tableCreate := "create table"
- if ifNotExists {
- s.WriteString(dialect.IfTableNotExists(tableCreate, t.SchemaName, t.TableName))
- } else {
- s.WriteString(tableCreate)
- }
- s.WriteString(fmt.Sprintf(" %s (", dialect.QuotedTableForQuery(t.SchemaName, t.TableName)))
-
- x := 0
- for _, col := range t.Columns {
- if !col.Transient {
- if x > 0 {
- s.WriteString(", ")
- }
- stype := dialect.ToSqlType(col.gotype, col.MaxSize, col.isAutoIncr)
- s.WriteString(fmt.Sprintf("%s %s", dialect.QuoteField(col.ColumnName), stype))
-
- if col.isPK || col.isNotNull {
- s.WriteString(" not null")
- }
- if col.isPK && len(t.keys) == 1 {
- s.WriteString(" primary key")
- }
- if col.Unique {
- s.WriteString(" unique")
- }
- if col.isAutoIncr {
- s.WriteString(fmt.Sprintf(" %s", dialect.AutoIncrStr()))
- }
-
- x++
- }
- }
- if len(t.keys) > 1 {
- s.WriteString(", primary key (")
- for x := range t.keys {
- if x > 0 {
- s.WriteString(", ")
- }
- s.WriteString(dialect.QuoteField(t.keys[x].ColumnName))
- }
- s.WriteString(")")
- }
- if len(t.uniqueTogether) > 0 {
- for _, columns := range t.uniqueTogether {
- s.WriteString(", unique (")
- for i, column := range columns {
- if i > 0 {
- s.WriteString(", ")
- }
- s.WriteString(dialect.QuoteField(column))
- }
- s.WriteString(")")
- }
- }
- s.WriteString(") ")
- s.WriteString(dialect.CreateTableSuffix())
- s.WriteString(dialect.QuerySuffix())
- return s.String()
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/table_bindings.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/table_bindings.go
deleted file mode 100644
index 1727d0d09..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/table_bindings.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "bytes"
- "fmt"
- "reflect"
-)
-
-// CustomScanner binds a database column value to a Go type
-type CustomScanner struct {
- // After a row is scanned, Holder will contain the value from the database column.
- // Initialize the CustomScanner with the concrete Go type you wish the database
- // driver to scan the raw column into.
- Holder interface{}
- // Target typically holds a pointer to the target struct field to bind the Holder
- // value to.
- Target interface{}
- // Binder is a custom function that converts the holder value to the target type
- // and sets target accordingly. This function should return error if a problem
- // occurs converting the holder to the target.
- Binder func(holder interface{}, target interface{}) error
-}
-
-// Used to filter columns when selectively updating
-type ColumnFilter func(*ColumnMap) bool
-
-func acceptAllFilter(col *ColumnMap) bool {
- return true
-}
-
-// Bind is called automatically by gorp after Scan()
-func (me CustomScanner) Bind() error {
- return me.Binder(me.Holder, me.Target)
-}
-
-type bindPlan struct {
- query string
- argFields []string
- keyFields []string
- versField string
- autoIncrIdx int
- autoIncrFieldName string
-}
-
-func (plan bindPlan) createBindInstance(elem reflect.Value, conv TypeConverter) (bindInstance, error) {
- bi := bindInstance{query: plan.query, autoIncrIdx: plan.autoIncrIdx, autoIncrFieldName: plan.autoIncrFieldName, versField: plan.versField}
- if plan.versField != "" {
- bi.existingVersion = elem.FieldByName(plan.versField).Int()
- }
-
- var err error
-
- for i := 0; i < len(plan.argFields); i++ {
- k := plan.argFields[i]
- if k == versFieldConst {
- newVer := bi.existingVersion + 1
- bi.args = append(bi.args, newVer)
- if bi.existingVersion == 0 {
- elem.FieldByName(plan.versField).SetInt(int64(newVer))
- }
- } else {
- val := elem.FieldByName(k).Interface()
- if conv != nil {
- val, err = conv.ToDb(val)
- if err != nil {
- return bindInstance{}, err
- }
- }
- bi.args = append(bi.args, val)
- }
- }
-
- for i := 0; i < len(plan.keyFields); i++ {
- k := plan.keyFields[i]
- val := elem.FieldByName(k).Interface()
- if conv != nil {
- val, err = conv.ToDb(val)
- if err != nil {
- return bindInstance{}, err
- }
- }
- bi.keys = append(bi.keys, val)
- }
-
- return bi, nil
-}
-
-type bindInstance struct {
- query string
- args []interface{}
- keys []interface{}
- existingVersion int64
- versField string
- autoIncrIdx int
- autoIncrFieldName string
-}
-
-func (t *TableMap) bindInsert(elem reflect.Value) (bindInstance, error) {
- plan := t.insertPlan
- if plan.query == "" {
- plan.autoIncrIdx = -1
-
- s := bytes.Buffer{}
- s2 := bytes.Buffer{}
- s.WriteString(fmt.Sprintf("insert into %s (", t.dbmap.Dialect.QuotedTableForQuery(t.SchemaName, t.TableName)))
-
- x := 0
- first := true
- for y := range t.Columns {
- col := t.Columns[y]
- if !(col.isAutoIncr && t.dbmap.Dialect.AutoIncrBindValue() == "") {
- if !col.Transient {
- if !first {
- s.WriteString(",")
- s2.WriteString(",")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(col.ColumnName))
-
- if col.isAutoIncr {
- s2.WriteString(t.dbmap.Dialect.AutoIncrBindValue())
- plan.autoIncrIdx = y
- plan.autoIncrFieldName = col.fieldName
- } else {
- if col.DefaultValue == "" {
- s2.WriteString(t.dbmap.Dialect.BindVar(x))
- if col == t.version {
- plan.versField = col.fieldName
- plan.argFields = append(plan.argFields, versFieldConst)
- } else {
- plan.argFields = append(plan.argFields, col.fieldName)
- }
- x++
- } else {
- s2.WriteString(col.DefaultValue)
- }
- }
- first = false
- }
- } else {
- plan.autoIncrIdx = y
- plan.autoIncrFieldName = col.fieldName
- }
- }
- s.WriteString(") values (")
- s.WriteString(s2.String())
- s.WriteString(")")
- if plan.autoIncrIdx > -1 {
- s.WriteString(t.dbmap.Dialect.AutoIncrInsertSuffix(t.Columns[plan.autoIncrIdx]))
- }
- s.WriteString(t.dbmap.Dialect.QuerySuffix())
-
- plan.query = s.String()
- t.insertPlan = plan
- }
-
- return plan.createBindInstance(elem, t.dbmap.TypeConverter)
-}
-
-func (t *TableMap) bindUpdate(elem reflect.Value, colFilter ColumnFilter) (bindInstance, error) {
- if colFilter == nil {
- colFilter = acceptAllFilter
- }
-
- plan := t.updatePlan
- if plan.query == "" {
-
- s := bytes.Buffer{}
- s.WriteString(fmt.Sprintf("update %s set ", t.dbmap.Dialect.QuotedTableForQuery(t.SchemaName, t.TableName)))
- x := 0
-
- for y := range t.Columns {
- col := t.Columns[y]
- if !col.isAutoIncr && !col.Transient && colFilter(col) {
- if x > 0 {
- s.WriteString(", ")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(col.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(x))
-
- if col == t.version {
- plan.versField = col.fieldName
- plan.argFields = append(plan.argFields, versFieldConst)
- } else {
- plan.argFields = append(plan.argFields, col.fieldName)
- }
- x++
- }
- }
-
- s.WriteString(" where ")
- for y := range t.keys {
- col := t.keys[y]
- if y > 0 {
- s.WriteString(" and ")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(col.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(x))
-
- plan.argFields = append(plan.argFields, col.fieldName)
- plan.keyFields = append(plan.keyFields, col.fieldName)
- x++
- }
- if plan.versField != "" {
- s.WriteString(" and ")
- s.WriteString(t.dbmap.Dialect.QuoteField(t.version.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(x))
- plan.argFields = append(plan.argFields, plan.versField)
- }
- s.WriteString(t.dbmap.Dialect.QuerySuffix())
-
- plan.query = s.String()
- t.updatePlan = plan
- }
-
- return plan.createBindInstance(elem, t.dbmap.TypeConverter)
-}
-
-func (t *TableMap) bindDelete(elem reflect.Value) (bindInstance, error) {
- plan := t.deletePlan
- if plan.query == "" {
-
- s := bytes.Buffer{}
- s.WriteString(fmt.Sprintf("delete from %s", t.dbmap.Dialect.QuotedTableForQuery(t.SchemaName, t.TableName)))
-
- for y := range t.Columns {
- col := t.Columns[y]
- if !col.Transient {
- if col == t.version {
- plan.versField = col.fieldName
- }
- }
- }
-
- s.WriteString(" where ")
- for x := range t.keys {
- k := t.keys[x]
- if x > 0 {
- s.WriteString(" and ")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(k.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(x))
-
- plan.keyFields = append(plan.keyFields, k.fieldName)
- plan.argFields = append(plan.argFields, k.fieldName)
- }
- if plan.versField != "" {
- s.WriteString(" and ")
- s.WriteString(t.dbmap.Dialect.QuoteField(t.version.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(len(plan.argFields)))
-
- plan.argFields = append(plan.argFields, plan.versField)
- }
- s.WriteString(t.dbmap.Dialect.QuerySuffix())
-
- plan.query = s.String()
- t.deletePlan = plan
- }
-
- return plan.createBindInstance(elem, t.dbmap.TypeConverter)
-}
-
-func (t *TableMap) bindGet() bindPlan {
- plan := t.getPlan
- if plan.query == "" {
-
- s := bytes.Buffer{}
- s.WriteString("select ")
-
- x := 0
- for _, col := range t.Columns {
- if !col.Transient {
- if x > 0 {
- s.WriteString(",")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(col.ColumnName))
- plan.argFields = append(plan.argFields, col.fieldName)
- x++
- }
- }
- s.WriteString(" from ")
- s.WriteString(t.dbmap.Dialect.QuotedTableForQuery(t.SchemaName, t.TableName))
- s.WriteString(" where ")
- for x := range t.keys {
- col := t.keys[x]
- if x > 0 {
- s.WriteString(" and ")
- }
- s.WriteString(t.dbmap.Dialect.QuoteField(col.ColumnName))
- s.WriteString("=")
- s.WriteString(t.dbmap.Dialect.BindVar(x))
-
- plan.keyFields = append(plan.keyFields, col.fieldName)
- }
- s.WriteString(t.dbmap.Dialect.QuerySuffix())
-
- plan.query = s.String()
- t.getPlan = plan
- }
-
- return plan
-}
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/test_all.sh b/Godeps/_workspace/src/github.com/go-gorp/gorp/test_all.sh
deleted file mode 100644
index f2d16961a..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/test_all.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash -e
-
-# on macs, you may need to:
-# export GOBUILDFLAG=-ldflags -linkmode=external
-
-coveralls_testflags="-v -covermode=count -coverprofile=coverage.out"
-
-echo "Testing against mysql"
-export GORP_TEST_DSN=gorptest/gorptest/gorptest
-export GORP_TEST_DIALECT=mysql
-go test $coveralls_testflags $GOBUILDFLAG $@ .
-
-echo "Testing against gomysql"
-export GORP_TEST_DSN=gorptest:gorptest@/gorptest
-export GORP_TEST_DIALECT=gomysql
-go test $coveralls_testflags $GOBUILDFLAG $@ .
-
-echo "Testing against postgres"
-export GORP_TEST_DSN="user=gorptest password=gorptest dbname=gorptest sslmode=disable"
-export GORP_TEST_DIALECT=postgres
-go test $coveralls_testflags $GOBUILDFLAG $@ .
-
-echo "Testing against sqlite"
-export GORP_TEST_DSN=/tmp/gorptest.bin
-export GORP_TEST_DIALECT=sqlite
-go test $coveralls_testflags $GOBUILDFLAG $@ .
-rm -f /tmp/gorptest.bin
-
-case $(go version) in
- *go1.4*)
- if [ "$(type -p goveralls)" != "" ]; then
- goveralls -covermode=count -coverprofile=coverage.out -service=travis-ci
- elif [ -x $HOME/gopath/bin/goveralls ]; then
- $HOME/gopath/bin/goveralls -covermode=count -coverprofile=coverage.out -service=travis-ci
- fi
- ;;
- *) ;;
-esac
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/transaction.go b/Godeps/_workspace/src/github.com/go-gorp/gorp/transaction.go
deleted file mode 100644
index 6430f24f1..000000000
--- a/Godeps/_workspace/src/github.com/go-gorp/gorp/transaction.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2012 James Cooper. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package gorp provides a simple way to marshal Go structs to and from
-// SQL databases. It uses the database/sql package, and should work with any
-// compliant database/sql driver.
-//
-// Source code and project home:
-// https://github.com/go-gorp/gorp
-
-package gorp
-
-import (
- "database/sql"
- "time"
-)
-
-// Transaction represents a database transaction.
-// Insert/Update/Delete/Get/Exec operations will be run in the context
-// of that transaction. Transactions should be terminated with
-// a call to Commit() or Rollback()
-type Transaction struct {
- dbmap *DbMap
- tx *sql.Tx
- closed bool
-}
-
-// Insert has the same behavior as DbMap.Insert(), but runs in a transaction.
-func (t *Transaction) Insert(list ...interface{}) error {
- return insert(t.dbmap, t, list...)
-}
-
-// Update had the same behavior as DbMap.Update(), but runs in a transaction.
-func (t *Transaction) Update(list ...interface{}) (int64, error) {
- return update(t.dbmap, t, nil, list...)
-}
-
-// UpdateColumns had the same behavior as DbMap.UpdateColumns(), but runs in a transaction.
-func (t *Transaction) UpdateColumns(filter ColumnFilter, list ...interface{}) (int64, error) {
- return update(t.dbmap, t, filter, list...)
-}
-
-// Delete has the same behavior as DbMap.Delete(), but runs in a transaction.
-func (t *Transaction) Delete(list ...interface{}) (int64, error) {
- return delete(t.dbmap, t, list...)
-}
-
-// Get has the same behavior as DbMap.Get(), but runs in a transaction.
-func (t *Transaction) Get(i interface{}, keys ...interface{}) (interface{}, error) {
- return get(t.dbmap, t, i, keys...)
-}
-
-// Select has the same behavior as DbMap.Select(), but runs in a transaction.
-func (t *Transaction) Select(i interface{}, query string, args ...interface{}) ([]interface{}, error) {
- return hookedselect(t.dbmap, t, i, query, args...)
-}
-
-// Exec has the same behavior as DbMap.Exec(), but runs in a transaction.
-func (t *Transaction) Exec(query string, args ...interface{}) (sql.Result, error) {
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, args...)
- }
- return exec(t, query, args...)
-}
-
-// SelectInt is a convenience wrapper around the gorp.SelectInt function.
-func (t *Transaction) SelectInt(query string, args ...interface{}) (int64, error) {
- return SelectInt(t, query, args...)
-}
-
-// SelectNullInt is a convenience wrapper around the gorp.SelectNullInt function.
-func (t *Transaction) SelectNullInt(query string, args ...interface{}) (sql.NullInt64, error) {
- return SelectNullInt(t, query, args...)
-}
-
-// SelectFloat is a convenience wrapper around the gorp.SelectFloat function.
-func (t *Transaction) SelectFloat(query string, args ...interface{}) (float64, error) {
- return SelectFloat(t, query, args...)
-}
-
-// SelectNullFloat is a convenience wrapper around the gorp.SelectNullFloat function.
-func (t *Transaction) SelectNullFloat(query string, args ...interface{}) (sql.NullFloat64, error) {
- return SelectNullFloat(t, query, args...)
-}
-
-// SelectStr is a convenience wrapper around the gorp.SelectStr function.
-func (t *Transaction) SelectStr(query string, args ...interface{}) (string, error) {
- return SelectStr(t, query, args...)
-}
-
-// SelectNullStr is a convenience wrapper around the gorp.SelectNullStr function.
-func (t *Transaction) SelectNullStr(query string, args ...interface{}) (sql.NullString, error) {
- return SelectNullStr(t, query, args...)
-}
-
-// SelectOne is a convenience wrapper around the gorp.SelectOne function.
-func (t *Transaction) SelectOne(holder interface{}, query string, args ...interface{}) error {
- return SelectOne(t.dbmap, t, holder, query, args...)
-}
-
-// Commit commits the underlying database transaction.
-func (t *Transaction) Commit() error {
- if !t.closed {
- t.closed = true
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, "commit;")
- }
- return t.tx.Commit()
- }
-
- return sql.ErrTxDone
-}
-
-// Rollback rolls back the underlying database transaction.
-func (t *Transaction) Rollback() error {
- if !t.closed {
- t.closed = true
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, "rollback;")
- }
- return t.tx.Rollback()
- }
-
- return sql.ErrTxDone
-}
-
-// Savepoint creates a savepoint with the given name. The name is interpolated
-// directly into the SQL SAVEPOINT statement, so you must sanitize it if it is
-// derived from user input.
-func (t *Transaction) Savepoint(name string) error {
- query := "savepoint " + t.dbmap.Dialect.QuoteField(name)
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, nil)
- }
- _, err := t.tx.Exec(query)
- return err
-}
-
-// RollbackToSavepoint rolls back to the savepoint with the given name. The
-// name is interpolated directly into the SQL SAVEPOINT statement, so you must
-// sanitize it if it is derived from user input.
-func (t *Transaction) RollbackToSavepoint(savepoint string) error {
- query := "rollback to savepoint " + t.dbmap.Dialect.QuoteField(savepoint)
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, nil)
- }
- _, err := t.tx.Exec(query)
- return err
-}
-
-// ReleaseSavepint releases the savepoint with the given name. The name is
-// interpolated directly into the SQL SAVEPOINT statement, so you must sanitize
-// it if it is derived from user input.
-func (t *Transaction) ReleaseSavepoint(savepoint string) error {
- query := "release savepoint " + t.dbmap.Dialect.QuoteField(savepoint)
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, nil)
- }
- _, err := t.tx.Exec(query)
- return err
-}
-
-// Prepare has the same behavior as DbMap.Prepare(), but runs in a transaction.
-func (t *Transaction) Prepare(query string) (*sql.Stmt, error) {
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, nil)
- }
- return t.tx.Prepare(query)
-}
-
-func (t *Transaction) queryRow(query string, args ...interface{}) *sql.Row {
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, args...)
- }
- return t.tx.QueryRow(query, args...)
-}
-
-func (t *Transaction) query(query string, args ...interface{}) (*sql.Rows, error) {
- if t.dbmap.logger != nil {
- now := time.Now()
- defer t.dbmap.trace(now, query, args...)
- }
- return t.tx.Query(query, args...)
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/.gitignore b/Godeps/_workspace/src/github.com/go-ldap/ldap/.gitignore
deleted file mode 100644
index e69de29bb..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/.gitignore
+++ /dev/null
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/.travis.yml b/Godeps/_workspace/src/github.com/go-ldap/ldap/.travis.yml
deleted file mode 100644
index a7a38951b..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: go
-go:
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - tip
-go_import_path: gopkg.in/ldap.v2
-install:
- - go get gopkg.in/asn1-ber.v1
- - go get gopkg.in/ldap.v2
- - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
- - go build -v ./...
-script:
- - go test -v -cover ./...
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/LICENSE b/Godeps/_workspace/src/github.com/go-ldap/ldap/LICENSE
deleted file mode 100644
index 744875676..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/README.md b/Godeps/_workspace/src/github.com/go-ldap/ldap/README.md
deleted file mode 100644
index 68121c3e2..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-[![GoDoc](https://godoc.org/gopkg.in/ldap.v1?status.svg)](https://godoc.org/gopkg.in/ldap.v1)
-[![Build Status](https://travis-ci.org/go-ldap/ldap.svg)](https://travis-ci.org/go-ldap/ldap)
-
-# Basic LDAP v3 functionality for the GO programming language.
-
-## Install
-
-For the latest version use:
-
- go get gopkg.in/ldap.v2
-
-Import the latest version with:
-
- import "gopkg.in/ldap.v2"
-
-
-## Required Libraries:
-
- - gopkg.in/asn1-ber.v1
-
-## Working:
-
- - Connecting to LDAP server
- - Binding to LDAP server
- - Searching for entries
- - Compiling string filters to LDAP filters
- - Paging Search Results
- - Modify Requests / Responses
- - Add Requests / Responses
- - Delete Requests / Responses
- - Better Unicode support
-
-## Examples:
-
- - search
- - modify
-
-## Tests Implemented:
-
- - Filter Compile / Decompile
-
-## TODO:
-
- - [x] Add Requests / Responses
- - [x] Delete Requests / Responses
- - [x] Modify DN Requests / Responses
- - [ ] Compare Requests / Responses
- - [ ] Implement Tests / Benchmarks
-
-
-
----
-The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
-The design is licensed under the Creative Commons 3.0 Attributions license.
-Read this article for more details: http://blog.golang.org/gopher
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/add.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/add.go
deleted file mode 100644
index 643ce5ffe..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/add.go
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// https://tools.ietf.org/html/rfc4511
-//
-// AddRequest ::= [APPLICATION 8] SEQUENCE {
-// entry LDAPDN,
-// attributes AttributeList }
-//
-// AttributeList ::= SEQUENCE OF attribute Attribute
-
-package ldap
-
-import (
- "errors"
- "log"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-type Attribute struct {
- attrType string
- attrVals []string
-}
-
-func (a *Attribute) encode() *ber.Packet {
- seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
- seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.attrType, "Type"))
- set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
- for _, value := range a.attrVals {
- set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
- }
- seq.AppendChild(set)
- return seq
-}
-
-type AddRequest struct {
- dn string
- attributes []Attribute
-}
-
-func (a AddRequest) encode() *ber.Packet {
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
- request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.dn, "DN"))
- attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
- for _, attribute := range a.attributes {
- attributes.AppendChild(attribute.encode())
- }
- request.AppendChild(attributes)
- return request
-}
-
-func (a *AddRequest) Attribute(attrType string, attrVals []string) {
- a.attributes = append(a.attributes, Attribute{attrType: attrType, attrVals: attrVals})
-}
-
-func NewAddRequest(dn string) *AddRequest {
- return &AddRequest{
- dn: dn,
- }
-
-}
-
-func (l *Conn) Add(addRequest *AddRequest) error {
- messageID := l.nextMessageID()
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- packet.AppendChild(addRequest.encode())
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return err
- }
- if channel == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- if packet == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return err
- }
- ber.PrintPacket(packet)
- }
-
- if packet.Children[1].Tag == ApplicationAddResponse {
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return NewError(resultCode, errors.New(resultDescription))
- }
- } else {
- log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
- }
-
- l.Debug.Printf("%d: returning", messageID)
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/bind.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/bind.go
deleted file mode 100644
index 4ad4b896c..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/bind.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ldap
-
-import (
- "errors"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-type SimpleBindRequest struct {
- Username string
- Password string
- Controls []Control
-}
-
-type SimpleBindResult struct {
- Controls []Control
-}
-
-func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest {
- return &SimpleBindRequest{
- Username: username,
- Password: password,
- Controls: controls,
- }
-}
-
-func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
- request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
- request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name"))
- request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password"))
-
- request.AppendChild(encodeControls(bindRequest.Controls))
-
- return request
-}
-
-func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
- messageID := l.nextMessageID()
-
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- encodedBindRequest := simpleBindRequest.encode()
- packet.AppendChild(encodedBindRequest)
-
- if l.Debug {
- ber.PrintPacket(packet)
- }
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return nil, err
- }
- if channel == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- packet = <-channel
- if packet == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return nil, err
- }
- ber.PrintPacket(packet)
- }
-
- result := &SimpleBindResult{
- Controls: make([]Control, 0),
- }
-
- if len(packet.Children) == 3 {
- for _, child := range packet.Children[2].Children {
- result.Controls = append(result.Controls, DecodeControl(child))
- }
- }
-
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return result, NewError(resultCode, errors.New(resultDescription))
- }
-
- return result, nil
-}
-
-func (l *Conn) Bind(username, password string) error {
- messageID := l.nextMessageID()
-
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
- bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
- bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name"))
- bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password"))
- packet.AppendChild(bindRequest)
-
- if l.Debug {
- ber.PrintPacket(packet)
- }
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return err
- }
- if channel == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- packet = <-channel
- if packet == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return err
- }
- ber.PrintPacket(packet)
- }
-
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return NewError(resultCode, errors.New(resultDescription))
- }
-
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/client.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/client.go
deleted file mode 100644
index d3401f9e6..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/client.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package ldap
-
-import "crypto/tls"
-
-// Client knows how to interact with an LDAP server
-type Client interface {
- Start()
- StartTLS(config *tls.Config) error
- Close()
-
- Bind(username, password string) error
- SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)
-
- Add(addRequest *AddRequest) error
- Del(delRequest *DelRequest) error
- Modify(modifyRequest *ModifyRequest) error
-
- Compare(dn, attribute, value string) (bool, error)
- PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
-
- Search(searchRequest *SearchRequest) (*SearchResult, error)
- SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/compare.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/compare.go
deleted file mode 100644
index 802e9cc93..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/compare.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// File contains Compare functionality
-//
-// https://tools.ietf.org/html/rfc4511
-//
-// CompareRequest ::= [APPLICATION 14] SEQUENCE {
-// entry LDAPDN,
-// ava AttributeValueAssertion }
-//
-// AttributeValueAssertion ::= SEQUENCE {
-// attributeDesc AttributeDescription,
-// assertionValue AssertionValue }
-//
-// AttributeDescription ::= LDAPString
-// -- Constrained to <attributedescription>
-// -- [RFC4512]
-//
-// AttributeValue ::= OCTET STRING
-//
-
-package ldap
-
-import (
- "errors"
- "fmt"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-// Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise
-// false with any error that occurs if any.
-func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
- messageID := l.nextMessageID()
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
-
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request")
- request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN"))
-
- ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion")
- ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "AttributeDesc"))
- ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagOctetString, value, "AssertionValue"))
- request.AppendChild(ava)
- packet.AppendChild(request)
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return false, err
- }
- if channel == nil {
- return false, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- if packet == nil {
- return false, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return false, err
- }
- ber.PrintPacket(packet)
- }
-
- if packet.Children[1].Tag == ApplicationCompareResponse {
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode == LDAPResultCompareTrue {
- return true, nil
- } else if resultCode == LDAPResultCompareFalse {
- return false, nil
- } else {
- return false, NewError(resultCode, errors.New(resultDescription))
- }
- }
- return false, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag)
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/conn.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/conn.go
deleted file mode 100644
index 2f16443f6..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/conn.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ldap
-
-import (
- "crypto/tls"
- "errors"
- "fmt"
- "log"
- "net"
- "sync"
- "time"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- MessageQuit = 0
- MessageRequest = 1
- MessageResponse = 2
- MessageFinish = 3
-)
-
-type messagePacket struct {
- Op int
- MessageID int64
- Packet *ber.Packet
- Channel chan *ber.Packet
-}
-
-type sendMessageFlags uint
-
-const (
- startTLS sendMessageFlags = 1 << iota
-)
-
-// Conn represents an LDAP Connection
-type Conn struct {
- conn net.Conn
- isTLS bool
- isClosing bool
- isStartingTLS bool
- Debug debugging
- chanConfirm chan bool
- chanResults map[int64]chan *ber.Packet
- chanMessage chan *messagePacket
- chanMessageID chan int64
- wgSender sync.WaitGroup
- wgClose sync.WaitGroup
- once sync.Once
- outstandingRequests uint
- messageMutex sync.Mutex
-}
-
-var _ Client = &Conn{}
-
-// DefaultTimeout is a package-level variable that sets the timeout value
-// used for the Dial and DialTLS methods.
-//
-// WARNING: since this is a package-level variable, setting this value from
-// multiple places will probably result in undesired behaviour.
-var DefaultTimeout = 60 * time.Second
-
-// Dial connects to the given address on the given network using net.Dial
-// and then returns a new Conn for the connection.
-func Dial(network, addr string) (*Conn, error) {
- c, err := net.DialTimeout(network, addr, DefaultTimeout)
- if err != nil {
- return nil, NewError(ErrorNetwork, err)
- }
- conn := NewConn(c, false)
- conn.Start()
- return conn, nil
-}
-
-// DialTLS connects to the given address on the given network using tls.Dial
-// and then returns a new Conn for the connection.
-func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
- dc, err := net.DialTimeout(network, addr, DefaultTimeout)
- if err != nil {
- return nil, NewError(ErrorNetwork, err)
- }
- c := tls.Client(dc, config)
- err = c.Handshake()
- if err != nil {
- // Handshake error, close the established connection before we return an error
- dc.Close()
- return nil, NewError(ErrorNetwork, err)
- }
- conn := NewConn(c, true)
- conn.Start()
- return conn, nil
-}
-
-// NewConn returns a new Conn using conn for network I/O.
-func NewConn(conn net.Conn, isTLS bool) *Conn {
- return &Conn{
- conn: conn,
- chanConfirm: make(chan bool),
- chanMessageID: make(chan int64),
- chanMessage: make(chan *messagePacket, 10),
- chanResults: map[int64]chan *ber.Packet{},
- isTLS: isTLS,
- }
-}
-
-func (l *Conn) Start() {
- go l.reader()
- go l.processMessages()
- l.wgClose.Add(1)
-}
-
-// Close closes the connection.
-func (l *Conn) Close() {
- l.once.Do(func() {
- l.isClosing = true
- l.wgSender.Wait()
-
- l.Debug.Printf("Sending quit message and waiting for confirmation")
- l.chanMessage <- &messagePacket{Op: MessageQuit}
- <-l.chanConfirm
- close(l.chanMessage)
-
- l.Debug.Printf("Closing network connection")
- if err := l.conn.Close(); err != nil {
- log.Print(err)
- }
-
- l.wgClose.Done()
- })
- l.wgClose.Wait()
-}
-
-// Returns the next available messageID
-func (l *Conn) nextMessageID() int64 {
- if l.chanMessageID != nil {
- if messageID, ok := <-l.chanMessageID; ok {
- return messageID
- }
- }
- return 0
-}
-
-// StartTLS sends the command to start a TLS session and then creates a new TLS Client
-func (l *Conn) StartTLS(config *tls.Config) error {
- messageID := l.nextMessageID()
-
- if l.isTLS {
- return NewError(ErrorNetwork, errors.New("ldap: already encrypted"))
- }
-
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS")
- request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command"))
- packet.AppendChild(request)
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessageWithFlags(packet, startTLS)
- if err != nil {
- return err
- }
- if channel == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- l.finishMessage(messageID)
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- l.Close()
- return err
- }
- ber.PrintPacket(packet)
- }
-
- if resultCode, message := getLDAPResultCode(packet); resultCode == LDAPResultSuccess {
- conn := tls.Client(l.conn, config)
-
- if err := conn.Handshake(); err != nil {
- l.Close()
- return NewError(ErrorNetwork, fmt.Errorf("TLS handshake failed (%v)", err))
- }
-
- l.isTLS = true
- l.conn = conn
- } else {
- return NewError(resultCode, fmt.Errorf("ldap: cannot StartTLS (%s)", message))
- }
- go l.reader()
-
- return nil
-}
-
-func (l *Conn) sendMessage(packet *ber.Packet) (chan *ber.Packet, error) {
- return l.sendMessageWithFlags(packet, 0)
-}
-
-func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (chan *ber.Packet, error) {
- if l.isClosing {
- return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
- }
- l.messageMutex.Lock()
- l.Debug.Printf("flags&startTLS = %d", flags&startTLS)
- if l.isStartingTLS {
- l.messageMutex.Unlock()
- return nil, NewError(ErrorNetwork, errors.New("ldap: connection is in startls phase."))
- }
- if flags&startTLS != 0 {
- if l.outstandingRequests != 0 {
- l.messageMutex.Unlock()
- return nil, NewError(ErrorNetwork, errors.New("ldap: cannot StartTLS with outstanding requests"))
- } else {
- l.isStartingTLS = true
- }
- }
- l.outstandingRequests++
-
- l.messageMutex.Unlock()
-
- out := make(chan *ber.Packet)
- message := &messagePacket{
- Op: MessageRequest,
- MessageID: packet.Children[0].Value.(int64),
- Packet: packet,
- Channel: out,
- }
- l.sendProcessMessage(message)
- return out, nil
-}
-
-func (l *Conn) finishMessage(messageID int64) {
- if l.isClosing {
- return
- }
-
- l.messageMutex.Lock()
- l.outstandingRequests--
- if l.isStartingTLS {
- l.isStartingTLS = false
- }
- l.messageMutex.Unlock()
-
- message := &messagePacket{
- Op: MessageFinish,
- MessageID: messageID,
- }
- l.sendProcessMessage(message)
-}
-
-func (l *Conn) sendProcessMessage(message *messagePacket) bool {
- if l.isClosing {
- return false
- }
- l.wgSender.Add(1)
- l.chanMessage <- message
- l.wgSender.Done()
- return true
-}
-
-func (l *Conn) processMessages() {
- defer func() {
- if err := recover(); err != nil {
- log.Printf("ldap: recovered panic in processMessages: %v", err)
- }
- for messageID, channel := range l.chanResults {
- l.Debug.Printf("Closing channel for MessageID %d", messageID)
- close(channel)
- delete(l.chanResults, messageID)
- }
- close(l.chanMessageID)
- l.chanConfirm <- true
- close(l.chanConfirm)
- }()
-
- var messageID int64 = 1
- for {
- select {
- case l.chanMessageID <- messageID:
- messageID++
- case messagePacket, ok := <-l.chanMessage:
- if !ok {
- l.Debug.Printf("Shutting down - message channel is closed")
- return
- }
- switch messagePacket.Op {
- case MessageQuit:
- l.Debug.Printf("Shutting down - quit message received")
- return
- case MessageRequest:
- // Add to message list and write to network
- l.Debug.Printf("Sending message %d", messagePacket.MessageID)
- l.chanResults[messagePacket.MessageID] = messagePacket.Channel
- // go routine
- buf := messagePacket.Packet.Bytes()
-
- _, err := l.conn.Write(buf)
- if err != nil {
- l.Debug.Printf("Error Sending Message: %s", err.Error())
- break
- }
- case MessageResponse:
- l.Debug.Printf("Receiving message %d", messagePacket.MessageID)
- if chanResult, ok := l.chanResults[messagePacket.MessageID]; ok {
- chanResult <- messagePacket.Packet
- } else {
- log.Printf("Received unexpected message %d", messagePacket.MessageID)
- ber.PrintPacket(messagePacket.Packet)
- }
- case MessageFinish:
- // Remove from message list
- l.Debug.Printf("Finished message %d", messagePacket.MessageID)
- close(l.chanResults[messagePacket.MessageID])
- delete(l.chanResults, messagePacket.MessageID)
- }
- }
- }
-}
-
-func (l *Conn) reader() {
- cleanstop := false
- defer func() {
- if err := recover(); err != nil {
- log.Printf("ldap: recovered panic in reader: %v", err)
- }
- if !cleanstop {
- l.Close()
- }
- }()
-
- for {
- if cleanstop {
- l.Debug.Printf("reader clean stopping (without closing the connection)")
- return
- }
- packet, err := ber.ReadPacket(l.conn)
- if err != nil {
- // A read error is expected here if we are closing the connection...
- if !l.isClosing {
- l.Debug.Printf("reader error: %s", err.Error())
- }
- return
- }
- addLDAPDescriptions(packet)
- if len(packet.Children) == 0 {
- l.Debug.Printf("Received bad ldap packet")
- continue
- }
- l.messageMutex.Lock()
- if l.isStartingTLS {
- cleanstop = true
- }
- l.messageMutex.Unlock()
- message := &messagePacket{
- Op: MessageResponse,
- MessageID: packet.Children[0].Value.(int64),
- Packet: packet,
- }
- if !l.sendProcessMessage(message) {
- return
- }
-
- }
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/control.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/control.go
deleted file mode 100644
index 4d8298093..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/control.go
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ldap
-
-import (
- "fmt"
- "strconv"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- ControlTypePaging = "1.2.840.113556.1.4.319"
- ControlTypeBeheraPasswordPolicy = "1.3.6.1.4.1.42.2.27.8.5.1"
- ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4"
- ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
- ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
-)
-
-var ControlTypeMap = map[string]string{
- ControlTypePaging: "Paging",
- ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
- ControlTypeManageDsaIT: "Manage DSA IT",
-}
-
-type Control interface {
- GetControlType() string
- Encode() *ber.Packet
- String() string
-}
-
-type ControlString struct {
- ControlType string
- Criticality bool
- ControlValue string
-}
-
-func (c *ControlString) GetControlType() string {
- return c.ControlType
-}
-
-func (c *ControlString) Encode() *ber.Packet {
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")"))
- if c.Criticality {
- packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
- }
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(c.ControlValue), "Control Value"))
- return packet
-}
-
-func (c *ControlString) String() string {
- return fmt.Sprintf("Control Type: %s (%q) Criticality: %t Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue)
-}
-
-type ControlPaging struct {
- PagingSize uint32
- Cookie []byte
-}
-
-func (c *ControlPaging) GetControlType() string {
- return ControlTypePaging
-}
-
-func (c *ControlPaging) Encode() *ber.Packet {
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")"))
-
- p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)")
- seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value")
- seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size"))
- cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
- cookie.Value = c.Cookie
- cookie.Data.Write(c.Cookie)
- seq.AppendChild(cookie)
- p2.AppendChild(seq)
-
- packet.AppendChild(p2)
- return packet
-}
-
-func (c *ControlPaging) String() string {
- return fmt.Sprintf(
- "Control Type: %s (%q) Criticality: %t PagingSize: %d Cookie: %q",
- ControlTypeMap[ControlTypePaging],
- ControlTypePaging,
- false,
- c.PagingSize,
- c.Cookie)
-}
-
-func (c *ControlPaging) SetCookie(cookie []byte) {
- c.Cookie = cookie
-}
-
-type ControlBeheraPasswordPolicy struct {
- Expire int64
- Grace int64
- Error int8
- ErrorString string
-}
-
-func (c *ControlBeheraPasswordPolicy) GetControlType() string {
- return ControlTypeBeheraPasswordPolicy
-}
-
-func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet {
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeBeheraPasswordPolicy, "Control Type ("+ControlTypeMap[ControlTypeBeheraPasswordPolicy]+")"))
-
- return packet
-}
-
-func (c *ControlBeheraPasswordPolicy) String() string {
- return fmt.Sprintf(
- "Control Type: %s (%q) Criticality: %t Expire: %d Grace: %d Error: %d, ErrorString: %s",
- ControlTypeMap[ControlTypeBeheraPasswordPolicy],
- ControlTypeBeheraPasswordPolicy,
- false,
- c.Expire,
- c.Grace,
- c.Error,
- c.ErrorString)
-}
-
-type ControlVChuPasswordMustChange struct {
- MustChange bool
-}
-
-func (c *ControlVChuPasswordMustChange) GetControlType() string {
- return ControlTypeVChuPasswordMustChange
-}
-
-func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet {
- return nil
-}
-
-func (c *ControlVChuPasswordMustChange) String() string {
- return fmt.Sprintf(
- "Control Type: %s (%q) Criticality: %t MustChange: %b",
- ControlTypeMap[ControlTypeVChuPasswordMustChange],
- ControlTypeVChuPasswordMustChange,
- false,
- c.MustChange)
-}
-
-type ControlVChuPasswordWarning struct {
- Expire int64
-}
-
-func (c *ControlVChuPasswordWarning) GetControlType() string {
- return ControlTypeVChuPasswordWarning
-}
-
-func (c *ControlVChuPasswordWarning) Encode() *ber.Packet {
- return nil
-}
-
-func (c *ControlVChuPasswordWarning) String() string {
- return fmt.Sprintf(
- "Control Type: %s (%q) Criticality: %t Expire: %b",
- ControlTypeMap[ControlTypeVChuPasswordWarning],
- ControlTypeVChuPasswordWarning,
- false,
- c.Expire)
-}
-
-type ControlManageDsaIT struct {
- Criticality bool
-}
-
-func (c *ControlManageDsaIT) GetControlType() string {
- return ControlTypeManageDsaIT
-}
-
-func (c *ControlManageDsaIT) Encode() *ber.Packet {
- //FIXME
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeManageDsaIT, "Control Type ("+ControlTypeMap[ControlTypeManageDsaIT]+")"))
- if c.Criticality {
- packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
- }
- return packet
-}
-
-func (c *ControlManageDsaIT) String() string {
- return fmt.Sprintf(
- "Control Type: %s (%q) Criticality: %t",
- ControlTypeMap[ControlTypeManageDsaIT],
- ControlTypeManageDsaIT,
- c.Criticality)
-}
-
-func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT {
- return &ControlManageDsaIT{Criticality: Criticality}
-}
-
-func FindControl(controls []Control, controlType string) Control {
- for _, c := range controls {
- if c.GetControlType() == controlType {
- return c
- }
- }
- return nil
-}
-
-func DecodeControl(packet *ber.Packet) Control {
- ControlType := packet.Children[0].Value.(string)
- Criticality := false
-
- packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
- value := packet.Children[1]
- if len(packet.Children) == 3 {
- value = packet.Children[2]
- packet.Children[1].Description = "Criticality"
- Criticality = packet.Children[1].Value.(bool)
- }
-
- value.Description = "Control Value"
- switch ControlType {
- case ControlTypePaging:
- value.Description += " (Paging)"
- c := new(ControlPaging)
- if value.Value != nil {
- valueChildren := ber.DecodePacket(value.Data.Bytes())
- value.Data.Truncate(0)
- value.Value = nil
- value.AppendChild(valueChildren)
- }
- value = value.Children[0]
- value.Description = "Search Control Value"
- value.Children[0].Description = "Paging Size"
- value.Children[1].Description = "Cookie"
- c.PagingSize = uint32(value.Children[0].Value.(int64))
- c.Cookie = value.Children[1].Data.Bytes()
- value.Children[1].Value = c.Cookie
- return c
- case ControlTypeBeheraPasswordPolicy:
- value.Description += " (Password Policy - Behera)"
- c := NewControlBeheraPasswordPolicy()
- if value.Value != nil {
- valueChildren := ber.DecodePacket(value.Data.Bytes())
- value.Data.Truncate(0)
- value.Value = nil
- value.AppendChild(valueChildren)
- }
-
- sequence := value.Children[0]
-
- for _, child := range sequence.Children {
- if child.Tag == 0 {
- //Warning
- child := child.Children[0]
- packet := ber.DecodePacket(child.Data.Bytes())
- val, ok := packet.Value.(int64)
- if ok {
- if child.Tag == 0 {
- //timeBeforeExpiration
- c.Expire = val
- child.Value = c.Expire
- } else if child.Tag == 1 {
- //graceAuthNsRemaining
- c.Grace = val
- child.Value = c.Grace
- }
- }
- } else if child.Tag == 1 {
- // Error
- packet := ber.DecodePacket(child.Data.Bytes())
- val, ok := packet.Value.(int8)
- if !ok {
- // what to do?
- val = -1
- }
- c.Error = val
- child.Value = c.Error
- c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
- }
- }
- return c
- case ControlTypeVChuPasswordMustChange:
- c := &ControlVChuPasswordMustChange{MustChange: true}
- return c
- case ControlTypeVChuPasswordWarning:
- c := &ControlVChuPasswordWarning{Expire: -1}
- expireStr := ber.DecodeString(value.Data.Bytes())
-
- expire, err := strconv.ParseInt(expireStr, 10, 64)
- if err != nil {
- return nil
- }
- c.Expire = expire
- value.Value = c.Expire
-
- return c
- }
- c := new(ControlString)
- c.ControlType = ControlType
- c.Criticality = Criticality
- c.ControlValue = value.Value.(string)
- return c
-}
-
-func NewControlString(controlType string, criticality bool, controlValue string) *ControlString {
- return &ControlString{
- ControlType: controlType,
- Criticality: criticality,
- ControlValue: controlValue,
- }
-}
-
-func NewControlPaging(pagingSize uint32) *ControlPaging {
- return &ControlPaging{PagingSize: pagingSize}
-}
-
-func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy {
- return &ControlBeheraPasswordPolicy{
- Expire: -1,
- Grace: -1,
- Error: -1,
- }
-}
-
-func encodeControls(controls []Control) *ber.Packet {
- packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls")
- for _, control := range controls {
- packet.AppendChild(control.Encode())
- }
- return packet
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/debug.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/debug.go
deleted file mode 100644
index b8a7ecbff..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/debug.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package ldap
-
-import (
- "log"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-// debbuging type
-// - has a Printf method to write the debug output
-type debugging bool
-
-// write debug output
-func (debug debugging) Printf(format string, args ...interface{}) {
- if debug {
- log.Printf(format, args...)
- }
-}
-
-func (debug debugging) PrintPacket(packet *ber.Packet) {
- if debug {
- ber.PrintPacket(packet)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/del.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/del.go
deleted file mode 100644
index 2f0eae1cd..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/del.go
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// https://tools.ietf.org/html/rfc4511
-//
-// DelRequest ::= [APPLICATION 10] LDAPDN
-
-package ldap
-
-import (
- "errors"
- "log"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-type DelRequest struct {
- DN string
- Controls []Control
-}
-
-func (d DelRequest) encode() *ber.Packet {
- request := ber.Encode(ber.ClassApplication, ber.TypePrimitive, ApplicationDelRequest, d.DN, "Del Request")
- request.Data.Write([]byte(d.DN))
- return request
-}
-
-func NewDelRequest(DN string,
- Controls []Control) *DelRequest {
- return &DelRequest{
- DN: DN,
- Controls: Controls,
- }
-}
-
-func (l *Conn) Del(delRequest *DelRequest) error {
- messageID := l.nextMessageID()
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- packet.AppendChild(delRequest.encode())
- if delRequest.Controls != nil {
- packet.AppendChild(encodeControls(delRequest.Controls))
- }
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return err
- }
- if channel == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- if packet == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return err
- }
- ber.PrintPacket(packet)
- }
-
- if packet.Children[1].Tag == ApplicationDelResponse {
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return NewError(resultCode, errors.New(resultDescription))
- }
- } else {
- log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
- }
-
- l.Debug.Printf("%d: returning", messageID)
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/dn.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/dn.go
deleted file mode 100644
index 5d83c5e9a..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/dn.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// File contains DN parsing functionallity
-//
-// https://tools.ietf.org/html/rfc4514
-//
-// distinguishedName = [ relativeDistinguishedName
-// *( COMMA relativeDistinguishedName ) ]
-// relativeDistinguishedName = attributeTypeAndValue
-// *( PLUS attributeTypeAndValue )
-// attributeTypeAndValue = attributeType EQUALS attributeValue
-// attributeType = descr / numericoid
-// attributeValue = string / hexstring
-//
-// ; The following characters are to be escaped when they appear
-// ; in the value to be encoded: ESC, one of <escaped>, leading
-// ; SHARP or SPACE, trailing SPACE, and NULL.
-// string = [ ( leadchar / pair ) [ *( stringchar / pair )
-// ( trailchar / pair ) ] ]
-//
-// leadchar = LUTF1 / UTFMB
-// LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A /
-// %x3D / %x3F-5B / %x5D-7F
-//
-// trailchar = TUTF1 / UTFMB
-// TUTF1 = %x01-1F / %x21 / %x23-2A / %x2D-3A /
-// %x3D / %x3F-5B / %x5D-7F
-//
-// stringchar = SUTF1 / UTFMB
-// SUTF1 = %x01-21 / %x23-2A / %x2D-3A /
-// %x3D / %x3F-5B / %x5D-7F
-//
-// pair = ESC ( ESC / special / hexpair )
-// special = escaped / SPACE / SHARP / EQUALS
-// escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
-// hexstring = SHARP 1*hexpair
-// hexpair = HEX HEX
-//
-// where the productions <descr>, <numericoid>, <COMMA>, <DQUOTE>,
-// <EQUALS>, <ESC>, <HEX>, <LANGLE>, <NULL>, <PLUS>, <RANGLE>, <SEMI>,
-// <SPACE>, <SHARP>, and <UTFMB> are defined in [RFC4512].
-//
-
-package ldap
-
-import (
- "bytes"
- enchex "encoding/hex"
- "errors"
- "fmt"
- "strings"
-
- ber "gopkg.in/asn1-ber.v1"
-)
-
-type AttributeTypeAndValue struct {
- Type string
- Value string
-}
-
-type RelativeDN struct {
- Attributes []*AttributeTypeAndValue
-}
-
-type DN struct {
- RDNs []*RelativeDN
-}
-
-func ParseDN(str string) (*DN, error) {
- dn := new(DN)
- dn.RDNs = make([]*RelativeDN, 0)
- rdn := new(RelativeDN)
- rdn.Attributes = make([]*AttributeTypeAndValue, 0)
- buffer := bytes.Buffer{}
- attribute := new(AttributeTypeAndValue)
- escaping := false
-
- for i := 0; i < len(str); i++ {
- char := str[i]
- if escaping {
- escaping = false
- switch char {
- case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\':
- buffer.WriteByte(char)
- continue
- }
- // Not a special character, assume hex encoded octet
- if len(str) == i+1 {
- return nil, errors.New("Got corrupted escaped character")
- }
-
- dst := []byte{0}
- n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
- if err != nil {
- return nil, errors.New(
- fmt.Sprintf("Failed to decode escaped character: %s", err))
- } else if n != 1 {
- return nil, errors.New(
- fmt.Sprintf("Expected 1 byte when un-escaping, got %d", n))
- }
- buffer.WriteByte(dst[0])
- i++
- } else if char == '\\' {
- escaping = true
- } else if char == '=' {
- attribute.Type = buffer.String()
- buffer.Reset()
- // Special case: If the first character in the value is # the
- // following data is BER encoded so we can just fast forward
- // and decode.
- if len(str) > i+1 && str[i+1] == '#' {
- i += 2
- index := strings.IndexAny(str[i:], ",+")
- data := str
- if index > 0 {
- data = str[i : i+index]
- } else {
- data = str[i:]
- }
- raw_ber, err := enchex.DecodeString(data)
- if err != nil {
- return nil, errors.New(
- fmt.Sprintf("Failed to decode BER encoding: %s", err))
- }
- packet := ber.DecodePacket(raw_ber)
- buffer.WriteString(packet.Data.String())
- i += len(data) - 1
- }
- } else if char == ',' || char == '+' {
- // We're done with this RDN or value, push it
- attribute.Value = buffer.String()
- rdn.Attributes = append(rdn.Attributes, attribute)
- attribute = new(AttributeTypeAndValue)
- if char == ',' {
- dn.RDNs = append(dn.RDNs, rdn)
- rdn = new(RelativeDN)
- rdn.Attributes = make([]*AttributeTypeAndValue, 0)
- }
- buffer.Reset()
- } else {
- buffer.WriteByte(char)
- }
- }
- if buffer.Len() > 0 {
- if len(attribute.Type) == 0 {
- return nil, errors.New("DN ended with incomplete type, value pair")
- }
- attribute.Value = buffer.String()
- rdn.Attributes = append(rdn.Attributes, attribute)
- dn.RDNs = append(dn.RDNs, rdn)
- }
- return dn, nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/doc.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/doc.go
deleted file mode 100644
index f20d39bc9..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/doc.go
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
-Package ldap provides basic LDAP v3 functionality.
-*/
-package ldap
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/error.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/error.go
deleted file mode 100644
index 2dbc30ac0..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/error.go
+++ /dev/null
@@ -1,137 +0,0 @@
-package ldap
-
-import (
- "fmt"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-// LDAP Result Codes
-const (
- LDAPResultSuccess = 0
- LDAPResultOperationsError = 1
- LDAPResultProtocolError = 2
- LDAPResultTimeLimitExceeded = 3
- LDAPResultSizeLimitExceeded = 4
- LDAPResultCompareFalse = 5
- LDAPResultCompareTrue = 6
- LDAPResultAuthMethodNotSupported = 7
- LDAPResultStrongAuthRequired = 8
- LDAPResultReferral = 10
- LDAPResultAdminLimitExceeded = 11
- LDAPResultUnavailableCriticalExtension = 12
- LDAPResultConfidentialityRequired = 13
- LDAPResultSaslBindInProgress = 14
- LDAPResultNoSuchAttribute = 16
- LDAPResultUndefinedAttributeType = 17
- LDAPResultInappropriateMatching = 18
- LDAPResultConstraintViolation = 19
- LDAPResultAttributeOrValueExists = 20
- LDAPResultInvalidAttributeSyntax = 21
- LDAPResultNoSuchObject = 32
- LDAPResultAliasProblem = 33
- LDAPResultInvalidDNSyntax = 34
- LDAPResultAliasDereferencingProblem = 36
- LDAPResultInappropriateAuthentication = 48
- LDAPResultInvalidCredentials = 49
- LDAPResultInsufficientAccessRights = 50
- LDAPResultBusy = 51
- LDAPResultUnavailable = 52
- LDAPResultUnwillingToPerform = 53
- LDAPResultLoopDetect = 54
- LDAPResultNamingViolation = 64
- LDAPResultObjectClassViolation = 65
- LDAPResultNotAllowedOnNonLeaf = 66
- LDAPResultNotAllowedOnRDN = 67
- LDAPResultEntryAlreadyExists = 68
- LDAPResultObjectClassModsProhibited = 69
- LDAPResultAffectsMultipleDSAs = 71
- LDAPResultOther = 80
-
- ErrorNetwork = 200
- ErrorFilterCompile = 201
- ErrorFilterDecompile = 202
- ErrorDebugging = 203
- ErrorUnexpectedMessage = 204
- ErrorUnexpectedResponse = 205
-)
-
-var LDAPResultCodeMap = map[uint8]string{
- LDAPResultSuccess: "Success",
- LDAPResultOperationsError: "Operations Error",
- LDAPResultProtocolError: "Protocol Error",
- LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
- LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
- LDAPResultCompareFalse: "Compare False",
- LDAPResultCompareTrue: "Compare True",
- LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
- LDAPResultStrongAuthRequired: "Strong Auth Required",
- LDAPResultReferral: "Referral",
- LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
- LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
- LDAPResultConfidentialityRequired: "Confidentiality Required",
- LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
- LDAPResultNoSuchAttribute: "No Such Attribute",
- LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
- LDAPResultInappropriateMatching: "Inappropriate Matching",
- LDAPResultConstraintViolation: "Constraint Violation",
- LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
- LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
- LDAPResultNoSuchObject: "No Such Object",
- LDAPResultAliasProblem: "Alias Problem",
- LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
- LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
- LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
- LDAPResultInvalidCredentials: "Invalid Credentials",
- LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
- LDAPResultBusy: "Busy",
- LDAPResultUnavailable: "Unavailable",
- LDAPResultUnwillingToPerform: "Unwilling To Perform",
- LDAPResultLoopDetect: "Loop Detect",
- LDAPResultNamingViolation: "Naming Violation",
- LDAPResultObjectClassViolation: "Object Class Violation",
- LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
- LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
- LDAPResultEntryAlreadyExists: "Entry Already Exists",
- LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
- LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
- LDAPResultOther: "Other",
-}
-
-func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
- if len(packet.Children) >= 2 {
- response := packet.Children[1]
- if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
- // Children[1].Children[2] is the diagnosticMessage which is guaranteed to exist as seen here: https://tools.ietf.org/html/rfc4511#section-4.1.9
- return uint8(response.Children[0].Value.(int64)), response.Children[2].Value.(string)
- }
- }
-
- return ErrorNetwork, "Invalid packet format"
-}
-
-type Error struct {
- Err error
- ResultCode uint8
-}
-
-func (e *Error) Error() string {
- return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
-}
-
-func NewError(resultCode uint8, err error) error {
- return &Error{ResultCode: resultCode, Err: err}
-}
-
-func IsErrorWithCode(err error, desiredResultCode uint8) bool {
- if err == nil {
- return false
- }
-
- serverError, ok := err.(*Error)
- if !ok {
- return false
- }
-
- return serverError.ResultCode == desiredResultCode
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/filter.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/filter.go
deleted file mode 100644
index 63bcec1e3..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/filter.go
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ldap
-
-import (
- "bytes"
- hexpac "encoding/hex"
- "errors"
- "fmt"
- "strings"
- "unicode/utf8"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- FilterAnd = 0
- FilterOr = 1
- FilterNot = 2
- FilterEqualityMatch = 3
- FilterSubstrings = 4
- FilterGreaterOrEqual = 5
- FilterLessOrEqual = 6
- FilterPresent = 7
- FilterApproxMatch = 8
- FilterExtensibleMatch = 9
-)
-
-var FilterMap = map[uint64]string{
- FilterAnd: "And",
- FilterOr: "Or",
- FilterNot: "Not",
- FilterEqualityMatch: "Equality Match",
- FilterSubstrings: "Substrings",
- FilterGreaterOrEqual: "Greater Or Equal",
- FilterLessOrEqual: "Less Or Equal",
- FilterPresent: "Present",
- FilterApproxMatch: "Approx Match",
- FilterExtensibleMatch: "Extensible Match",
-}
-
-const (
- FilterSubstringsInitial = 0
- FilterSubstringsAny = 1
- FilterSubstringsFinal = 2
-)
-
-var FilterSubstringsMap = map[uint64]string{
- FilterSubstringsInitial: "Substrings Initial",
- FilterSubstringsAny: "Substrings Any",
- FilterSubstringsFinal: "Substrings Final",
-}
-
-const (
- MatchingRuleAssertionMatchingRule = 1
- MatchingRuleAssertionType = 2
- MatchingRuleAssertionMatchValue = 3
- MatchingRuleAssertionDNAttributes = 4
-)
-
-var MatchingRuleAssertionMap = map[uint64]string{
- MatchingRuleAssertionMatchingRule: "Matching Rule Assertion Matching Rule",
- MatchingRuleAssertionType: "Matching Rule Assertion Type",
- MatchingRuleAssertionMatchValue: "Matching Rule Assertion Match Value",
- MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
-}
-
-func CompileFilter(filter string) (*ber.Packet, error) {
- if len(filter) == 0 || filter[0] != '(' {
- return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('"))
- }
- packet, pos, err := compileFilter(filter, 1)
- if err != nil {
- return nil, err
- }
- if pos != len(filter) {
- return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:])))
- }
- return packet, nil
-}
-
-func DecompileFilter(packet *ber.Packet) (ret string, err error) {
- defer func() {
- if r := recover(); r != nil {
- err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter"))
- }
- }()
- ret = "("
- err = nil
- childStr := ""
-
- switch packet.Tag {
- case FilterAnd:
- ret += "&"
- for _, child := range packet.Children {
- childStr, err = DecompileFilter(child)
- if err != nil {
- return
- }
- ret += childStr
- }
- case FilterOr:
- ret += "|"
- for _, child := range packet.Children {
- childStr, err = DecompileFilter(child)
- if err != nil {
- return
- }
- ret += childStr
- }
- case FilterNot:
- ret += "!"
- childStr, err = DecompileFilter(packet.Children[0])
- if err != nil {
- return
- }
- ret += childStr
-
- case FilterSubstrings:
- ret += ber.DecodeString(packet.Children[0].Data.Bytes())
- ret += "="
- for i, child := range packet.Children[1].Children {
- if i == 0 && child.Tag != FilterSubstringsInitial {
- ret += "*"
- }
- ret += EscapeFilter(ber.DecodeString(child.Data.Bytes()))
- if child.Tag != FilterSubstringsFinal {
- ret += "*"
- }
- }
- case FilterEqualityMatch:
- ret += ber.DecodeString(packet.Children[0].Data.Bytes())
- ret += "="
- ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
- case FilterGreaterOrEqual:
- ret += ber.DecodeString(packet.Children[0].Data.Bytes())
- ret += ">="
- ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
- case FilterLessOrEqual:
- ret += ber.DecodeString(packet.Children[0].Data.Bytes())
- ret += "<="
- ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
- case FilterPresent:
- ret += ber.DecodeString(packet.Data.Bytes())
- ret += "=*"
- case FilterApproxMatch:
- ret += ber.DecodeString(packet.Children[0].Data.Bytes())
- ret += "~="
- ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
- case FilterExtensibleMatch:
- attr := ""
- dnAttributes := false
- matchingRule := ""
- value := ""
-
- for _, child := range packet.Children {
- switch child.Tag {
- case MatchingRuleAssertionMatchingRule:
- matchingRule = ber.DecodeString(child.Data.Bytes())
- case MatchingRuleAssertionType:
- attr = ber.DecodeString(child.Data.Bytes())
- case MatchingRuleAssertionMatchValue:
- value = ber.DecodeString(child.Data.Bytes())
- case MatchingRuleAssertionDNAttributes:
- dnAttributes = child.Value.(bool)
- }
- }
-
- if len(attr) > 0 {
- ret += attr
- }
- if dnAttributes {
- ret += ":dn"
- }
- if len(matchingRule) > 0 {
- ret += ":"
- ret += matchingRule
- }
- ret += ":="
- ret += EscapeFilter(value)
- }
-
- ret += ")"
- return
-}
-
-func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) {
- for pos < len(filter) && filter[pos] == '(' {
- child, newPos, err := compileFilter(filter, pos+1)
- if err != nil {
- return pos, err
- }
- pos = newPos
- parent.AppendChild(child)
- }
- if pos == len(filter) {
- return pos, NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter"))
- }
-
- return pos + 1, nil
-}
-
-func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
- var (
- packet *ber.Packet
- err error
- )
-
- defer func() {
- if r := recover(); r != nil {
- err = NewError(ErrorFilterCompile, errors.New("ldap: error compiling filter"))
- }
- }()
- newPos := pos
-
- currentRune, currentWidth := utf8.DecodeRuneInString(filter[newPos:])
-
- switch currentRune {
- case utf8.RuneError:
- return nil, 0, NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", newPos))
- case '(':
- packet, newPos, err = compileFilter(filter, pos+currentWidth)
- newPos++
- return packet, newPos, err
- case '&':
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[FilterAnd])
- newPos, err = compileFilterSet(filter, pos+currentWidth, packet)
- return packet, newPos, err
- case '|':
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[FilterOr])
- newPos, err = compileFilterSet(filter, pos+currentWidth, packet)
- return packet, newPos, err
- case '!':
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[FilterNot])
- var child *ber.Packet
- child, newPos, err = compileFilter(filter, pos+currentWidth)
- packet.AppendChild(child)
- return packet, newPos, err
- default:
- READING_ATTR := 0
- READING_EXTENSIBLE_MATCHING_RULE := 1
- READING_CONDITION := 2
-
- state := READING_ATTR
-
- attribute := ""
- extensibleDNAttributes := false
- extensibleMatchingRule := ""
- condition := ""
-
- for newPos < len(filter) {
- remainingFilter := filter[newPos:]
- currentRune, currentWidth = utf8.DecodeRuneInString(remainingFilter)
- if currentRune == ')' {
- break
- }
- if currentRune == utf8.RuneError {
- return packet, newPos, NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", newPos))
- }
-
- switch state {
- case READING_ATTR:
- switch {
- // Extensible rule, with only DN-matching
- case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:="):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
- extensibleDNAttributes = true
- state = READING_CONDITION
- newPos += 5
-
- // Extensible rule, with DN-matching and a matching OID
- case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:"):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
- extensibleDNAttributes = true
- state = READING_EXTENSIBLE_MATCHING_RULE
- newPos += 4
-
- // Extensible rule, with attr only
- case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
- state = READING_CONDITION
- newPos += 2
-
- // Extensible rule, with no DN attribute matching
- case currentRune == ':':
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
- state = READING_EXTENSIBLE_MATCHING_RULE
- newPos += 1
-
- // Equality condition
- case currentRune == '=':
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch])
- state = READING_CONDITION
- newPos += 1
-
- // Greater-than or equal
- case currentRune == '>' && strings.HasPrefix(remainingFilter, ">="):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual])
- state = READING_CONDITION
- newPos += 2
-
- // Less-than or equal
- case currentRune == '<' && strings.HasPrefix(remainingFilter, "<="):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual])
- state = READING_CONDITION
- newPos += 2
-
- // Approx
- case currentRune == '~' && strings.HasPrefix(remainingFilter, "~="):
- packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterApproxMatch])
- state = READING_CONDITION
- newPos += 2
-
- // Still reading the attribute name
- default:
- attribute += fmt.Sprintf("%c", currentRune)
- newPos += currentWidth
- }
-
- case READING_EXTENSIBLE_MATCHING_RULE:
- switch {
-
- // Matching rule OID is done
- case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
- state = READING_CONDITION
- newPos += 2
-
- // Still reading the matching rule oid
- default:
- extensibleMatchingRule += fmt.Sprintf("%c", currentRune)
- newPos += currentWidth
- }
-
- case READING_CONDITION:
- // append to the condition
- condition += fmt.Sprintf("%c", currentRune)
- newPos += currentWidth
- }
- }
-
- if newPos == len(filter) {
- err = NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter"))
- return packet, newPos, err
- }
- if packet == nil {
- err = NewError(ErrorFilterCompile, errors.New("ldap: error parsing filter"))
- return packet, newPos, err
- }
-
- switch {
- case packet.Tag == FilterExtensibleMatch:
- // MatchingRuleAssertion ::= SEQUENCE {
- // matchingRule [1] MatchingRuleID OPTIONAL,
- // type [2] AttributeDescription OPTIONAL,
- // matchValue [3] AssertionValue,
- // dnAttributes [4] BOOLEAN DEFAULT FALSE
- // }
-
- // Include the matching rule oid, if specified
- if len(extensibleMatchingRule) > 0 {
- packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchingRule, extensibleMatchingRule, MatchingRuleAssertionMap[MatchingRuleAssertionMatchingRule]))
- }
-
- // Include the attribute, if specified
- if len(attribute) > 0 {
- packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionType, attribute, MatchingRuleAssertionMap[MatchingRuleAssertionType]))
- }
-
- // Add the value (only required child)
- encodedString, err := escapedStringToEncodedBytes(condition)
- if err != nil {
- return packet, newPos, err
- }
- packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchValue, encodedString, MatchingRuleAssertionMap[MatchingRuleAssertionMatchValue]))
-
- // Defaults to false, so only include in the sequence if true
- if extensibleDNAttributes {
- packet.AppendChild(ber.NewBoolean(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionDNAttributes, extensibleDNAttributes, MatchingRuleAssertionMap[MatchingRuleAssertionDNAttributes]))
- }
-
- case packet.Tag == FilterEqualityMatch && condition == "*":
- packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute, FilterMap[FilterPresent])
- case packet.Tag == FilterEqualityMatch && strings.Contains(condition, "*"):
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))
- packet.Tag = FilterSubstrings
- packet.Description = FilterMap[uint64(packet.Tag)]
- seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")
- parts := strings.Split(condition, "*")
- for i, part := range parts {
- if part == "" {
- continue
- }
- var tag ber.Tag
- switch i {
- case 0:
- tag = FilterSubstringsInitial
- case len(parts) - 1:
- tag = FilterSubstringsFinal
- default:
- tag = FilterSubstringsAny
- }
- encodedString, err := escapedStringToEncodedBytes(part)
- if err != nil {
- return packet, newPos, err
- }
- seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, tag, encodedString, FilterSubstringsMap[uint64(tag)]))
- }
- packet.AppendChild(seq)
- default:
- encodedString, err := escapedStringToEncodedBytes(condition)
- if err != nil {
- return packet, newPos, err
- }
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))
- packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, encodedString, "Condition"))
- }
-
- newPos += currentWidth
- return packet, newPos, err
- }
-}
-
-// Convert from "ABC\xx\xx\xx" form to literal bytes for transport
-func escapedStringToEncodedBytes(escapedString string) (string, error) {
- var buffer bytes.Buffer
- i := 0
- for i < len(escapedString) {
- currentRune, currentWidth := utf8.DecodeRuneInString(escapedString[i:])
- if currentRune == utf8.RuneError {
- return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", i))
- }
-
- // Check for escaped hex characters and convert them to their literal value for transport.
- if currentRune == '\\' {
- // http://tools.ietf.org/search/rfc4515
- // \ (%x5C) is not a valid character unless it is followed by two HEX characters due to not
- // being a member of UTF1SUBSET.
- if i+2 > len(escapedString) {
- return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter"))
- }
- if escByte, decodeErr := hexpac.DecodeString(escapedString[i+1 : i+3]); decodeErr != nil {
- return "", NewError(ErrorFilterCompile, errors.New("ldap: invalid characters for escape in filter"))
- } else {
- buffer.WriteByte(escByte[0])
- i += 2 // +1 from end of loop, so 3 total for \xx.
- }
- } else {
- buffer.WriteRune(currentRune)
- }
-
- i += currentWidth
- }
- return buffer.String(), nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/ldap.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/ldap.go
deleted file mode 100644
index 1620aaea6..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/ldap.go
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ldap
-
-import (
- "errors"
- "io/ioutil"
- "os"
-
- ber "gopkg.in/asn1-ber.v1"
-)
-
-// LDAP Application Codes
-const (
- ApplicationBindRequest = 0
- ApplicationBindResponse = 1
- ApplicationUnbindRequest = 2
- ApplicationSearchRequest = 3
- ApplicationSearchResultEntry = 4
- ApplicationSearchResultDone = 5
- ApplicationModifyRequest = 6
- ApplicationModifyResponse = 7
- ApplicationAddRequest = 8
- ApplicationAddResponse = 9
- ApplicationDelRequest = 10
- ApplicationDelResponse = 11
- ApplicationModifyDNRequest = 12
- ApplicationModifyDNResponse = 13
- ApplicationCompareRequest = 14
- ApplicationCompareResponse = 15
- ApplicationAbandonRequest = 16
- ApplicationSearchResultReference = 19
- ApplicationExtendedRequest = 23
- ApplicationExtendedResponse = 24
-)
-
-var ApplicationMap = map[uint8]string{
- ApplicationBindRequest: "Bind Request",
- ApplicationBindResponse: "Bind Response",
- ApplicationUnbindRequest: "Unbind Request",
- ApplicationSearchRequest: "Search Request",
- ApplicationSearchResultEntry: "Search Result Entry",
- ApplicationSearchResultDone: "Search Result Done",
- ApplicationModifyRequest: "Modify Request",
- ApplicationModifyResponse: "Modify Response",
- ApplicationAddRequest: "Add Request",
- ApplicationAddResponse: "Add Response",
- ApplicationDelRequest: "Del Request",
- ApplicationDelResponse: "Del Response",
- ApplicationModifyDNRequest: "Modify DN Request",
- ApplicationModifyDNResponse: "Modify DN Response",
- ApplicationCompareRequest: "Compare Request",
- ApplicationCompareResponse: "Compare Response",
- ApplicationAbandonRequest: "Abandon Request",
- ApplicationSearchResultReference: "Search Result Reference",
- ApplicationExtendedRequest: "Extended Request",
- ApplicationExtendedResponse: "Extended Response",
-}
-
-// Ldap Behera Password Policy Draft 10 (https://tools.ietf.org/html/draft-behera-ldap-password-policy-10)
-const (
- BeheraPasswordExpired = 0
- BeheraAccountLocked = 1
- BeheraChangeAfterReset = 2
- BeheraPasswordModNotAllowed = 3
- BeheraMustSupplyOldPassword = 4
- BeheraInsufficientPasswordQuality = 5
- BeheraPasswordTooShort = 6
- BeheraPasswordTooYoung = 7
- BeheraPasswordInHistory = 8
-)
-
-var BeheraPasswordPolicyErrorMap = map[int8]string{
- BeheraPasswordExpired: "Password expired",
- BeheraAccountLocked: "Account locked",
- BeheraChangeAfterReset: "Password must be changed",
- BeheraPasswordModNotAllowed: "Policy prevents password modification",
- BeheraMustSupplyOldPassword: "Policy requires old password in order to change password",
- BeheraInsufficientPasswordQuality: "Password fails quality checks",
- BeheraPasswordTooShort: "Password is too short for policy",
- BeheraPasswordTooYoung: "Password has been changed too recently",
- BeheraPasswordInHistory: "New password is in list of old passwords",
-}
-
-// Adds descriptions to an LDAP Response packet for debugging
-func addLDAPDescriptions(packet *ber.Packet) (err error) {
- defer func() {
- if r := recover(); r != nil {
- err = NewError(ErrorDebugging, errors.New("ldap: cannot process packet to add descriptions"))
- }
- }()
- packet.Description = "LDAP Response"
- packet.Children[0].Description = "Message ID"
-
- application := uint8(packet.Children[1].Tag)
- packet.Children[1].Description = ApplicationMap[application]
-
- switch application {
- case ApplicationBindRequest:
- addRequestDescriptions(packet)
- case ApplicationBindResponse:
- addDefaultLDAPResponseDescriptions(packet)
- case ApplicationUnbindRequest:
- addRequestDescriptions(packet)
- case ApplicationSearchRequest:
- addRequestDescriptions(packet)
- case ApplicationSearchResultEntry:
- packet.Children[1].Children[0].Description = "Object Name"
- packet.Children[1].Children[1].Description = "Attributes"
- for _, child := range packet.Children[1].Children[1].Children {
- child.Description = "Attribute"
- child.Children[0].Description = "Attribute Name"
- child.Children[1].Description = "Attribute Values"
- for _, grandchild := range child.Children[1].Children {
- grandchild.Description = "Attribute Value"
- }
- }
- if len(packet.Children) == 3 {
- addControlDescriptions(packet.Children[2])
- }
- case ApplicationSearchResultDone:
- addDefaultLDAPResponseDescriptions(packet)
- case ApplicationModifyRequest:
- addRequestDescriptions(packet)
- case ApplicationModifyResponse:
- case ApplicationAddRequest:
- addRequestDescriptions(packet)
- case ApplicationAddResponse:
- case ApplicationDelRequest:
- addRequestDescriptions(packet)
- case ApplicationDelResponse:
- case ApplicationModifyDNRequest:
- addRequestDescriptions(packet)
- case ApplicationModifyDNResponse:
- case ApplicationCompareRequest:
- addRequestDescriptions(packet)
- case ApplicationCompareResponse:
- case ApplicationAbandonRequest:
- addRequestDescriptions(packet)
- case ApplicationSearchResultReference:
- case ApplicationExtendedRequest:
- addRequestDescriptions(packet)
- case ApplicationExtendedResponse:
- }
-
- return nil
-}
-
-func addControlDescriptions(packet *ber.Packet) {
- packet.Description = "Controls"
- for _, child := range packet.Children {
- child.Description = "Control"
- child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")"
- value := child.Children[1]
- if len(child.Children) == 3 {
- child.Children[1].Description = "Criticality"
- value = child.Children[2]
- }
- value.Description = "Control Value"
-
- switch child.Children[0].Value.(string) {
- case ControlTypePaging:
- value.Description += " (Paging)"
- if value.Value != nil {
- valueChildren := ber.DecodePacket(value.Data.Bytes())
- value.Data.Truncate(0)
- value.Value = nil
- valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes()
- value.AppendChild(valueChildren)
- }
- value.Children[0].Description = "Real Search Control Value"
- value.Children[0].Children[0].Description = "Paging Size"
- value.Children[0].Children[1].Description = "Cookie"
-
- case ControlTypeBeheraPasswordPolicy:
- value.Description += " (Password Policy - Behera Draft)"
- if value.Value != nil {
- valueChildren := ber.DecodePacket(value.Data.Bytes())
- value.Data.Truncate(0)
- value.Value = nil
- value.AppendChild(valueChildren)
- }
- sequence := value.Children[0]
- for _, child := range sequence.Children {
- if child.Tag == 0 {
- //Warning
- child := child.Children[0]
- packet := ber.DecodePacket(child.Data.Bytes())
- val, ok := packet.Value.(int64)
- if ok {
- if child.Tag == 0 {
- //timeBeforeExpiration
- value.Description += " (TimeBeforeExpiration)"
- child.Value = val
- } else if child.Tag == 1 {
- //graceAuthNsRemaining
- value.Description += " (GraceAuthNsRemaining)"
- child.Value = val
- }
- }
- } else if child.Tag == 1 {
- // Error
- packet := ber.DecodePacket(child.Data.Bytes())
- val, ok := packet.Value.(int8)
- if !ok {
- val = -1
- }
- child.Description = "Error"
- child.Value = val
- }
- }
- }
- }
-}
-
-func addRequestDescriptions(packet *ber.Packet) {
- packet.Description = "LDAP Request"
- packet.Children[0].Description = "Message ID"
- packet.Children[1].Description = ApplicationMap[uint8(packet.Children[1].Tag)]
- if len(packet.Children) == 3 {
- addControlDescriptions(packet.Children[2])
- }
-}
-
-func addDefaultLDAPResponseDescriptions(packet *ber.Packet) {
- resultCode, _ := getLDAPResultCode(packet)
- packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")"
- packet.Children[1].Children[1].Description = "Matched DN"
- packet.Children[1].Children[2].Description = "Error Message"
- if len(packet.Children[1].Children) > 3 {
- packet.Children[1].Children[3].Description = "Referral"
- }
- if len(packet.Children) == 3 {
- addControlDescriptions(packet.Children[2])
- }
-}
-
-func DebugBinaryFile(fileName string) error {
- file, err := ioutil.ReadFile(fileName)
- if err != nil {
- return NewError(ErrorDebugging, err)
- }
- ber.PrintBytes(os.Stdout, file, "")
- packet := ber.DecodePacket(file)
- addLDAPDescriptions(packet)
- ber.PrintPacket(packet)
-
- return nil
-}
-
-var hex = "0123456789abcdef"
-
-func mustEscape(c byte) bool {
- return c > 0x7f || c == '(' || c == ')' || c == '\\' || c == '*' || c == 0
-}
-
-// EscapeFilter escapes from the provided LDAP filter string the special
-// characters in the set `()*\` and those out of the range 0 < c < 0x80,
-// as defined in RFC4515.
-func EscapeFilter(filter string) string {
- escape := 0
- for i := 0; i < len(filter); i++ {
- if mustEscape(filter[i]) {
- escape++
- }
- }
- if escape == 0 {
- return filter
- }
- buf := make([]byte, len(filter)+escape*2)
- for i, j := 0, 0; i < len(filter); i++ {
- c := filter[i]
- if mustEscape(c) {
- buf[j+0] = '\\'
- buf[j+1] = hex[c>>4]
- buf[j+2] = hex[c&0xf]
- j += 3
- } else {
- buf[j] = c
- j++
- }
- }
- return string(buf)
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/modify.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/modify.go
deleted file mode 100644
index 4372a19dc..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/modify.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// File contains Modify functionality
-//
-// https://tools.ietf.org/html/rfc4511
-//
-// ModifyRequest ::= [APPLICATION 6] SEQUENCE {
-// object LDAPDN,
-// changes SEQUENCE OF change SEQUENCE {
-// operation ENUMERATED {
-// add (0),
-// delete (1),
-// replace (2),
-// ... },
-// modification PartialAttribute } }
-//
-// PartialAttribute ::= SEQUENCE {
-// type AttributeDescription,
-// vals SET OF value AttributeValue }
-//
-// AttributeDescription ::= LDAPString
-// -- Constrained to <attributedescription>
-// -- [RFC4512]
-//
-// AttributeValue ::= OCTET STRING
-//
-
-package ldap
-
-import (
- "errors"
- "log"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- AddAttribute = 0
- DeleteAttribute = 1
- ReplaceAttribute = 2
-)
-
-type PartialAttribute struct {
- attrType string
- attrVals []string
-}
-
-func (p *PartialAttribute) encode() *ber.Packet {
- seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute")
- seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.attrType, "Type"))
- set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
- for _, value := range p.attrVals {
- set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
- }
- seq.AppendChild(set)
- return seq
-}
-
-type ModifyRequest struct {
- dn string
- addAttributes []PartialAttribute
- deleteAttributes []PartialAttribute
- replaceAttributes []PartialAttribute
-}
-
-func (m *ModifyRequest) Add(attrType string, attrVals []string) {
- m.addAttributes = append(m.addAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
-}
-
-func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
- m.deleteAttributes = append(m.deleteAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
-}
-
-func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
- m.replaceAttributes = append(m.replaceAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
-}
-
-func (m ModifyRequest) encode() *ber.Packet {
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request")
- request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.dn, "DN"))
- changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes")
- for _, attribute := range m.addAttributes {
- change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
- change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
- change.AppendChild(attribute.encode())
- changes.AppendChild(change)
- }
- for _, attribute := range m.deleteAttributes {
- change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
- change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation"))
- change.AppendChild(attribute.encode())
- changes.AppendChild(change)
- }
- for _, attribute := range m.replaceAttributes {
- change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
- change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation"))
- change.AppendChild(attribute.encode())
- changes.AppendChild(change)
- }
- request.AppendChild(changes)
- return request
-}
-
-func NewModifyRequest(
- dn string,
-) *ModifyRequest {
- return &ModifyRequest{
- dn: dn,
- }
-}
-
-func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
- messageID := l.nextMessageID()
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- packet.AppendChild(modifyRequest.encode())
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return err
- }
- if channel == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- if packet == nil {
- return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return err
- }
- ber.PrintPacket(packet)
- }
-
- if packet.Children[1].Tag == ApplicationModifyResponse {
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return NewError(resultCode, errors.New(resultDescription))
- }
- } else {
- log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
- }
-
- l.Debug.Printf("%d: returning", messageID)
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/passwdmodify.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/passwdmodify.go
deleted file mode 100644
index 508b11ed7..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/passwdmodify.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// This file contains the password modify extended operation as specified in rfc 3062
-//
-// https://tools.ietf.org/html/rfc3062
-//
-
-package ldap
-
-import (
- "errors"
- "fmt"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- passwordModifyOID = "1.3.6.1.4.1.4203.1.11.1"
-)
-
-type PasswordModifyRequest struct {
- UserIdentity string
- OldPassword string
- NewPassword string
-}
-
-type PasswordModifyResult struct {
- GeneratedPassword string
-}
-
-func (r *PasswordModifyRequest) encode() (*ber.Packet, error) {
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Password Modify Extended Operation")
- request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, passwordModifyOID, "Extended Request Name: Password Modify OID"))
- extendedRequestValue := ber.Encode(ber.ClassContext, ber.TypePrimitive, 1, nil, "Extended Request Value: Password Modify Request")
- passwordModifyRequestValue := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Password Modify Request")
- if r.UserIdentity != "" {
- passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, r.UserIdentity, "User Identity"))
- }
- if r.OldPassword != "" {
- passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 1, r.OldPassword, "Old Password"))
- }
- if r.NewPassword != "" {
- passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 2, r.NewPassword, "New Password"))
- }
-
- extendedRequestValue.AppendChild(passwordModifyRequestValue)
- request.AppendChild(extendedRequestValue)
-
- return request, nil
-}
-
-// Create a new PasswordModifyRequest
-//
-// According to the RFC 3602:
-// userIdentity is a string representing the user associated with the request.
-// This string may or may not be an LDAPDN (RFC 2253).
-// If userIdentity is empty then the operation will act on the user associated
-// with the session.
-//
-// oldPassword is the current user's password, it can be empty or it can be
-// needed depending on the session user access rights (usually an administrator
-// can change a user's password without knowing the current one) and the
-// password policy (see pwdSafeModify password policy's attribute)
-//
-// newPassword is the desired user's password. If empty the server can return
-// an error or generate a new password that will be available in the
-// PasswordModifyResult.GeneratedPassword
-//
-func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPassword string) *PasswordModifyRequest {
- return &PasswordModifyRequest{
- UserIdentity: userIdentity,
- OldPassword: oldPassword,
- NewPassword: newPassword,
- }
-}
-
-func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) {
- messageID := l.nextMessageID()
-
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
-
- encodedPasswordModifyRequest, err := passwordModifyRequest.encode()
- if err != nil {
- return nil, err
- }
- packet.AppendChild(encodedPasswordModifyRequest)
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return nil, err
- }
- if channel == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- result := &PasswordModifyResult{}
-
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
-
- if packet == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return nil, err
- }
- ber.PrintPacket(packet)
- }
-
- if packet.Children[1].Tag == ApplicationExtendedResponse {
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return nil, NewError(resultCode, errors.New(resultDescription))
- }
- } else {
- return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag))
- }
-
- extendedResponse := packet.Children[1]
- for _, child := range extendedResponse.Children {
- if child.Tag == 11 {
- passwordModifyReponseValue := ber.DecodePacket(child.Data.Bytes())
- if len(passwordModifyReponseValue.Children) == 1 {
- if passwordModifyReponseValue.Children[0].Tag == 0 {
- result.GeneratedPassword = ber.DecodeString(passwordModifyReponseValue.Children[0].Data.Bytes())
- }
- }
- }
- }
-
- return result, nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-ldap/ldap/search.go b/Godeps/_workspace/src/github.com/go-ldap/ldap/search.go
deleted file mode 100644
index f63c9fb02..000000000
--- a/Godeps/_workspace/src/github.com/go-ldap/ldap/search.go
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// File contains Search functionality
-//
-// https://tools.ietf.org/html/rfc4511
-//
-// SearchRequest ::= [APPLICATION 3] SEQUENCE {
-// baseObject LDAPDN,
-// scope ENUMERATED {
-// baseObject (0),
-// singleLevel (1),
-// wholeSubtree (2),
-// ... },
-// derefAliases ENUMERATED {
-// neverDerefAliases (0),
-// derefInSearching (1),
-// derefFindingBaseObj (2),
-// derefAlways (3) },
-// sizeLimit INTEGER (0 .. maxInt),
-// timeLimit INTEGER (0 .. maxInt),
-// typesOnly BOOLEAN,
-// filter Filter,
-// attributes AttributeSelection }
-//
-// AttributeSelection ::= SEQUENCE OF selector LDAPString
-// -- The LDAPString is constrained to
-// -- <attributeSelector> in Section 4.5.1.8
-//
-// Filter ::= CHOICE {
-// and [0] SET SIZE (1..MAX) OF filter Filter,
-// or [1] SET SIZE (1..MAX) OF filter Filter,
-// not [2] Filter,
-// equalityMatch [3] AttributeValueAssertion,
-// substrings [4] SubstringFilter,
-// greaterOrEqual [5] AttributeValueAssertion,
-// lessOrEqual [6] AttributeValueAssertion,
-// present [7] AttributeDescription,
-// approxMatch [8] AttributeValueAssertion,
-// extensibleMatch [9] MatchingRuleAssertion,
-// ... }
-//
-// SubstringFilter ::= SEQUENCE {
-// type AttributeDescription,
-// substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
-// initial [0] AssertionValue, -- can occur at most once
-// any [1] AssertionValue,
-// final [2] AssertionValue } -- can occur at most once
-// }
-//
-// MatchingRuleAssertion ::= SEQUENCE {
-// matchingRule [1] MatchingRuleId OPTIONAL,
-// type [2] AttributeDescription OPTIONAL,
-// matchValue [3] AssertionValue,
-// dnAttributes [4] BOOLEAN DEFAULT FALSE }
-//
-//
-
-package ldap
-
-import (
- "errors"
- "fmt"
- "sort"
- "strings"
-
- "gopkg.in/asn1-ber.v1"
-)
-
-const (
- ScopeBaseObject = 0
- ScopeSingleLevel = 1
- ScopeWholeSubtree = 2
-)
-
-var ScopeMap = map[int]string{
- ScopeBaseObject: "Base Object",
- ScopeSingleLevel: "Single Level",
- ScopeWholeSubtree: "Whole Subtree",
-}
-
-const (
- NeverDerefAliases = 0
- DerefInSearching = 1
- DerefFindingBaseObj = 2
- DerefAlways = 3
-)
-
-var DerefMap = map[int]string{
- NeverDerefAliases: "NeverDerefAliases",
- DerefInSearching: "DerefInSearching",
- DerefFindingBaseObj: "DerefFindingBaseObj",
- DerefAlways: "DerefAlways",
-}
-
-// NewEntry returns an Entry object with the specified distinguished name and attribute key-value pairs.
-// The map of attributes is accessed in alphabetical order of the keys in order to ensure that, for the
-// same input map of attributes, the output entry will contain the same order of attributes
-func NewEntry(dn string, attributes map[string][]string) *Entry {
- var attributeNames []string
- for attributeName := range attributes {
- attributeNames = append(attributeNames, attributeName)
- }
- sort.Strings(attributeNames)
-
- var encodedAttributes []*EntryAttribute
- for _, attributeName := range attributeNames {
- encodedAttributes = append(encodedAttributes, NewEntryAttribute(attributeName, attributes[attributeName]))
- }
- return &Entry{
- DN: dn,
- Attributes: encodedAttributes,
- }
-}
-
-type Entry struct {
- DN string
- Attributes []*EntryAttribute
-}
-
-func (e *Entry) GetAttributeValues(attribute string) []string {
- for _, attr := range e.Attributes {
- if attr.Name == attribute {
- return attr.Values
- }
- }
- return []string{}
-}
-
-func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
- for _, attr := range e.Attributes {
- if attr.Name == attribute {
- return attr.ByteValues
- }
- }
- return [][]byte{}
-}
-
-func (e *Entry) GetAttributeValue(attribute string) string {
- values := e.GetAttributeValues(attribute)
- if len(values) == 0 {
- return ""
- }
- return values[0]
-}
-
-func (e *Entry) GetRawAttributeValue(attribute string) []byte {
- values := e.GetRawAttributeValues(attribute)
- if len(values) == 0 {
- return []byte{}
- }
- return values[0]
-}
-
-func (e *Entry) Print() {
- fmt.Printf("DN: %s\n", e.DN)
- for _, attr := range e.Attributes {
- attr.Print()
- }
-}
-
-func (e *Entry) PrettyPrint(indent int) {
- fmt.Printf("%sDN: %s\n", strings.Repeat(" ", indent), e.DN)
- for _, attr := range e.Attributes {
- attr.PrettyPrint(indent + 2)
- }
-}
-
-// NewEntryAttribute returns a new EntryAttribute with the desired key-value pair
-func NewEntryAttribute(name string, values []string) *EntryAttribute {
- var bytes [][]byte
- for _, value := range values {
- bytes = append(bytes, []byte(value))
- }
- return &EntryAttribute{
- Name: name,
- Values: values,
- ByteValues: bytes,
- }
-}
-
-type EntryAttribute struct {
- Name string
- Values []string
- ByteValues [][]byte
-}
-
-func (e *EntryAttribute) Print() {
- fmt.Printf("%s: %s\n", e.Name, e.Values)
-}
-
-func (e *EntryAttribute) PrettyPrint(indent int) {
- fmt.Printf("%s%s: %s\n", strings.Repeat(" ", indent), e.Name, e.Values)
-}
-
-type SearchResult struct {
- Entries []*Entry
- Referrals []string
- Controls []Control
-}
-
-func (s *SearchResult) Print() {
- for _, entry := range s.Entries {
- entry.Print()
- }
-}
-
-func (s *SearchResult) PrettyPrint(indent int) {
- for _, entry := range s.Entries {
- entry.PrettyPrint(indent)
- }
-}
-
-type SearchRequest struct {
- BaseDN string
- Scope int
- DerefAliases int
- SizeLimit int
- TimeLimit int
- TypesOnly bool
- Filter string
- Attributes []string
- Controls []Control
-}
-
-func (s *SearchRequest) encode() (*ber.Packet, error) {
- request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationSearchRequest, nil, "Search Request")
- request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, s.BaseDN, "Base DN"))
- request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.Scope), "Scope"))
- request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.DerefAliases), "Deref Aliases"))
- request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.SizeLimit), "Size Limit"))
- request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.TimeLimit), "Time Limit"))
- request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, s.TypesOnly, "Types Only"))
- // compile and encode filter
- filterPacket, err := CompileFilter(s.Filter)
- if err != nil {
- return nil, err
- }
- request.AppendChild(filterPacket)
- // encode attributes
- attributesPacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
- for _, attribute := range s.Attributes {
- attributesPacket.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))
- }
- request.AppendChild(attributesPacket)
- return request, nil
-}
-
-func NewSearchRequest(
- BaseDN string,
- Scope, DerefAliases, SizeLimit, TimeLimit int,
- TypesOnly bool,
- Filter string,
- Attributes []string,
- Controls []Control,
-) *SearchRequest {
- return &SearchRequest{
- BaseDN: BaseDN,
- Scope: Scope,
- DerefAliases: DerefAliases,
- SizeLimit: SizeLimit,
- TimeLimit: TimeLimit,
- TypesOnly: TypesOnly,
- Filter: Filter,
- Attributes: Attributes,
- Controls: Controls,
- }
-}
-
-func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) {
- if searchRequest.Controls == nil {
- searchRequest.Controls = make([]Control, 0)
- }
-
- pagingControl := NewControlPaging(pagingSize)
- searchRequest.Controls = append(searchRequest.Controls, pagingControl)
- searchResult := new(SearchResult)
- for {
- result, err := l.Search(searchRequest)
- l.Debug.Printf("Looking for Paging Control...")
- if err != nil {
- return searchResult, err
- }
- if result == nil {
- return searchResult, NewError(ErrorNetwork, errors.New("ldap: packet not received"))
- }
-
- for _, entry := range result.Entries {
- searchResult.Entries = append(searchResult.Entries, entry)
- }
- for _, referral := range result.Referrals {
- searchResult.Referrals = append(searchResult.Referrals, referral)
- }
- for _, control := range result.Controls {
- searchResult.Controls = append(searchResult.Controls, control)
- }
-
- l.Debug.Printf("Looking for Paging Control...")
- pagingResult := FindControl(result.Controls, ControlTypePaging)
- if pagingResult == nil {
- pagingControl = nil
- l.Debug.Printf("Could not find paging control. Breaking...")
- break
- }
-
- cookie := pagingResult.(*ControlPaging).Cookie
- if len(cookie) == 0 {
- pagingControl = nil
- l.Debug.Printf("Could not find cookie. Breaking...")
- break
- }
- pagingControl.SetCookie(cookie)
- }
-
- if pagingControl != nil {
- l.Debug.Printf("Abandoning Paging...")
- pagingControl.PagingSize = 0
- l.Search(searchRequest)
- }
-
- return searchResult, nil
-}
-
-func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
- messageID := l.nextMessageID()
- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
- // encode search request
- encodedSearchRequest, err := searchRequest.encode()
- if err != nil {
- return nil, err
- }
- packet.AppendChild(encodedSearchRequest)
- // encode search controls
- if searchRequest.Controls != nil {
- packet.AppendChild(encodeControls(searchRequest.Controls))
- }
-
- l.Debug.PrintPacket(packet)
-
- channel, err := l.sendMessage(packet)
- if err != nil {
- return nil, err
- }
- if channel == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
- }
- defer l.finishMessage(messageID)
-
- result := &SearchResult{
- Entries: make([]*Entry, 0),
- Referrals: make([]string, 0),
- Controls: make([]Control, 0)}
-
- foundSearchResultDone := false
- for !foundSearchResultDone {
- l.Debug.Printf("%d: waiting for response", messageID)
- packet = <-channel
- l.Debug.Printf("%d: got response %p", messageID, packet)
- if packet == nil {
- return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
- }
-
- if l.Debug {
- if err := addLDAPDescriptions(packet); err != nil {
- return nil, err
- }
- ber.PrintPacket(packet)
- }
-
- switch packet.Children[1].Tag {
- case 4:
- entry := new(Entry)
- entry.DN = packet.Children[1].Children[0].Value.(string)
- for _, child := range packet.Children[1].Children[1].Children {
- attr := new(EntryAttribute)
- attr.Name = child.Children[0].Value.(string)
- for _, value := range child.Children[1].Children {
- attr.Values = append(attr.Values, value.Value.(string))
- attr.ByteValues = append(attr.ByteValues, value.ByteValue)
- }
- entry.Attributes = append(entry.Attributes, attr)
- }
- result.Entries = append(result.Entries, entry)
- case 5:
- resultCode, resultDescription := getLDAPResultCode(packet)
- if resultCode != 0 {
- return result, NewError(resultCode, errors.New(resultDescription))
- }
- if len(packet.Children) == 3 {
- for _, child := range packet.Children[2].Children {
- result.Controls = append(result.Controls, DecodeControl(child))
- }
- }
- foundSearchResultDone = true
- case 19:
- result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string))
- }
- }
- l.Debug.Printf("%d: returning", messageID)
- return result, nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore
deleted file mode 100644
index ba8e0cb3a..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.DS_Store
-.DS_Store?
-._*
-.Spotlight-V100
-.Trashes
-Icon?
-ehthumbs.db
-Thumbs.db
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml
deleted file mode 100644
index 2f4e3c2f0..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-sudo: false
-language: go
-go:
- - 1.2
- - 1.3
- - 1.4
- - tip
-
-before_script:
- - mysql -e 'create database gotest;'
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS
deleted file mode 100644
index 6dd0167f3..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS
+++ /dev/null
@@ -1,46 +0,0 @@
-# This is the official list of Go-MySQL-Driver authors for copyright purposes.
-
-# If you are submitting a patch, please add your name or the name of the
-# organization which holds the copyright to this list in alphabetical order.
-
-# Names should be added to this file as
-# Name <email address>
-# The email address is not required for organizations.
-# Please keep the list sorted.
-
-
-# Individual Persons
-
-Aaron Hopkins <go-sql-driver at die.net>
-Arne Hormann <arnehormann at gmail.com>
-Carlos Nieto <jose.carlos at menteslibres.net>
-Chris Moos <chris at tech9computers.com>
-DisposaBoy <disposaboy at dby.me>
-Frederick Mayle <frederickmayle at gmail.com>
-Gustavo Kristic <gkristic at gmail.com>
-Hanno Braun <mail at hannobraun.com>
-Henri Yandell <flamefew at gmail.com>
-Hirotaka Yamamoto <ymmt2005 at gmail.com>
-INADA Naoki <songofacandy at gmail.com>
-James Harr <james.harr at gmail.com>
-Jian Zhen <zhenjl at gmail.com>
-Joshua Prunier <joshua.prunier at gmail.com>
-Julien Schmidt <go-sql-driver at julienschmidt.com>
-Kamil Dziedzic <kamil at klecza.pl>
-Leonardo YongUk Kim <dalinaum at gmail.com>
-Lucas Liu <extrafliu at gmail.com>
-Luke Scott <luke at webconnex.com>
-Michael Woolnough <michael.woolnough at gmail.com>
-Nicola Peduzzi <thenikso at gmail.com>
-Runrioter Wung <runrioter at gmail.com>
-Soroush Pour <me at soroushjp.com>
-Stan Putrya <root.vagner at gmail.com>
-Xiaobing Jiang <s7v7nislands at gmail.com>
-Xiuming Chen <cc at cxm.cc>
-Julien Lefevre <julien.lefevr at gmail.com>
-
-# Organizations
-
-Barracuda Networks, Inc.
-Google Inc.
-Stripe Inc.
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CHANGELOG.md b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CHANGELOG.md
deleted file mode 100644
index 161ad0fcc..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CHANGELOG.md
+++ /dev/null
@@ -1,92 +0,0 @@
-## HEAD
-
-Changes:
-
- - Go 1.1 is no longer supported
- - Use decimals field from MySQL to format time types (#249)
- - Buffer optimizations (#269)
- - TLS ServerName defaults to the host (#283)
-
-Bugfixes:
-
- - Enable microsecond resolution on TIME, DATETIME and TIMESTAMP (#249)
- - Fixed handling of queries without columns and rows (#255)
- - Fixed a panic when SetKeepAlive() failed (#298)
-
-New Features:
- - Support for returning table alias on Columns() (#289)
- - Placeholder interpolation, can be actived with the DSN parameter `interpolateParams=true` (#309, #318)
-
-
-## Version 1.2 (2014-06-03)
-
-Changes:
-
- - We switched back to a "rolling release". `go get` installs the current master branch again
- - Version v1 of the driver will not be maintained anymore. Go 1.0 is no longer supported by this driver
- - Exported errors to allow easy checking from application code
- - Enabled TCP Keepalives on TCP connections
- - Optimized INFILE handling (better buffer size calculation, lazy init, ...)
- - The DSN parser also checks for a missing separating slash
- - Faster binary date / datetime to string formatting
- - Also exported the MySQLWarning type
- - mysqlConn.Close returns the first error encountered instead of ignoring all errors
- - writePacket() automatically writes the packet size to the header
- - readPacket() uses an iterative approach instead of the recursive approach to merge splitted packets
-
-New Features:
-
- - `RegisterDial` allows the usage of a custom dial function to establish the network connection
- - Setting the connection collation is possible with the `collation` DSN parameter. This parameter should be preferred over the `charset` parameter
- - Logging of critical errors is configurable with `SetLogger`
- - Google CloudSQL support
-
-Bugfixes:
-
- - Allow more than 32 parameters in prepared statements
- - Various old_password fixes
- - Fixed TestConcurrent test to pass Go's race detection
- - Fixed appendLengthEncodedInteger for large numbers
- - Renamed readLengthEnodedString to readLengthEncodedString and skipLengthEnodedString to skipLengthEncodedString (fixed typo)
-
-
-## Version 1.1 (2013-11-02)
-
-Changes:
-
- - Go-MySQL-Driver now requires Go 1.1
- - Connections now use the collation `utf8_general_ci` by default. Adding `&charset=UTF8` to the DSN should not be necessary anymore
- - Made closing rows and connections error tolerant. This allows for example deferring rows.Close() without checking for errors
- - `[]byte(nil)` is now treated as a NULL value. Before, it was treated like an empty string / `[]byte("")`
- - DSN parameter values must now be url.QueryEscape'ed. This allows text values to contain special characters, such as '&'.
- - Use the IO buffer also for writing. This results in zero allocations (by the driver) for most queries
- - Optimized the buffer for reading
- - stmt.Query now caches column metadata
- - New Logo
- - Changed the copyright header to include all contributors
- - Improved the LOAD INFILE documentation
- - The driver struct is now exported to make the driver directly accessible
- - Refactored the driver tests
- - Added more benchmarks and moved all to a separate file
- - Other small refactoring
-
-New Features:
-
- - Added *old_passwords* support: Required in some cases, but must be enabled by adding `allowOldPasswords=true` to the DSN since it is insecure
- - Added a `clientFoundRows` parameter: Return the number of matching rows instead of the number of rows changed on UPDATEs
- - Added TLS/SSL support: Use a TLS/SSL encrypted connection to the server. Custom TLS configs can be registered and used
-
-Bugfixes:
-
- - Fixed MySQL 4.1 support: MySQL 4.1 sends packets with lengths which differ from the specification
- - Convert to DB timezone when inserting `time.Time`
- - Splitted packets (more than 16MB) are now merged correctly
- - Fixed false positive `io.EOF` errors when the data was fully read
- - Avoid panics on reuse of closed connections
- - Fixed empty string producing false nil values
- - Fixed sign byte for positive TIME fields
-
-
-## Version 1.0 (2013-05-14)
-
-Initial Release
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CONTRIBUTING.md
deleted file mode 100644
index f87c19824..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/CONTRIBUTING.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Contributing Guidelines
-
-## Reporting Issues
-
-Before creating a new Issue, please check first if a similar Issue [already exists](https://github.com/go-sql-driver/mysql/issues?state=open) or was [recently closed](https://github.com/go-sql-driver/mysql/issues?direction=desc&page=1&sort=updated&state=closed).
-
-Please provide the following minimum information:
-* Your Go-MySQL-Driver version (or git SHA)
-* Your Go version (run `go version` in your console)
-* A detailed issue description
-* Error Log if present
-* If possible, a short example
-
-
-## Contributing Code
-
-By contributing to this project, you share your code under the Mozilla Public License 2, as specified in the LICENSE file.
-Don't forget to add yourself to the AUTHORS file.
-
-### Pull Requests Checklist
-
-Please check the following points before submitting your pull request:
-- [x] Code compiles correctly
-- [x] Created tests, if possible
-- [x] All tests pass
-- [x] Extended the README / documentation, if necessary
-- [x] Added yourself to the AUTHORS file
-
-### Code Review
-
-Everyone is invited to review and comment on pull requests.
-If it looks fine to you, comment with "LGTM" (Looks good to me).
-
-If changes are required, notice the reviewers with "PTAL" (Please take another look) after committing the fixes.
-
-Before merging the Pull Request, at least one [team member](https://github.com/go-sql-driver?tab=members) must have commented with "LGTM".
-
-## Development Ideas
-
-If you are looking for ideas for code contributions, please check our [Development Ideas](https://github.com/go-sql-driver/mysql/wiki/Development-Ideas) Wiki page.
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/LICENSE b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/LICENSE
deleted file mode 100644
index 14e2f777f..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/LICENSE
+++ /dev/null
@@ -1,373 +0,0 @@
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
- means each individual or legal entity that creates, contributes to
- the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
- means the combination of the Contributions of others (if any) used
- by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
- means Source Code Form to which the initial Contributor has attached
- the notice in Exhibit A, the Executable Form of such Source Code
- Form, and Modifications of such Source Code Form, in each case
- including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- (a) that the initial Contributor has attached the notice described
- in Exhibit B to the Covered Software; or
-
- (b) that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the
- terms of a Secondary License.
-
-1.6. "Executable Form"
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
- means a work that combines Covered Software with other material, in
- a separate file or files, that is not Covered Software.
-
-1.8. "License"
- means this document.
-
-1.9. "Licensable"
- means having the right to grant, to the maximum extent possible,
- whether at the time of the initial grant or subsequently, any and
- all of the rights conveyed by this License.
-
-1.10. "Modifications"
- means any of the following:
-
- (a) any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered
- Software; or
-
- (b) any new file in Source Code Form that contains any Covered
- Software.
-
-1.11. "Patent Claims" of a Contributor
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the
- License, by the making, using, selling, offering for sale, having
- made, import, or transfer of either its Contributions or its
- Contributor Version.
-
-1.12. "Secondary License"
- means either the GNU General Public License, Version 2.0, the GNU
- Lesser General Public License, Version 2.1, the GNU Affero General
- Public License, Version 3.0, or any later versions of those
- licenses.
-
-1.13. "Source Code Form"
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that
- controls, is controlled by, or is under common control with You. For
- purposes of this definition, "control" means (a) the power, direct
- or indirect, to cause the direction or management of such entity,
- whether by contract or otherwise, or (b) ownership of more than
- fifty percent (50%) of the outstanding shares or beneficial
- ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
- for sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
- or
-
-(b) for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
- Form, as described in Section 3.1, and You must inform recipients of
- the Executable Form how they can obtain a copy of such Source Code
- Form by reasonable means in a timely manner, at a charge no more
- than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter
- the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-* *
-* 6. Disclaimer of Warranty *
-* ------------------------- *
-* *
-* Covered Software is provided under this License on an "as is" *
-* basis, without warranty of any kind, either expressed, implied, or *
-* statutory, including, without limitation, warranties that the *
-* Covered Software is free of defects, merchantable, fit for a *
-* particular purpose or non-infringing. The entire risk as to the *
-* quality and performance of the Covered Software is with You. *
-* Should any Covered Software prove defective in any respect, You *
-* (not any Contributor) assume the cost of any necessary servicing, *
-* repair, or correction. This disclaimer of warranty constitutes an *
-* essential part of this License. No use of any Covered Software is *
-* authorized under this License except under this disclaimer. *
-* *
-************************************************************************
-
-************************************************************************
-* *
-* 7. Limitation of Liability *
-* -------------------------- *
-* *
-* Under no circumstances and under no legal theory, whether tort *
-* (including negligence), contract, or otherwise, shall any *
-* Contributor, or anyone who distributes Covered Software as *
-* permitted above, be liable to You for any direct, indirect, *
-* special, incidental, or consequential damages of any character *
-* including, without limitation, damages for lost profits, loss of *
-* goodwill, work stoppage, computer failure or malfunction, or any *
-* and all other commercial damages or losses, even if such party *
-* shall have been informed of the possibility of such damages. This *
-* limitation of liability shall not apply to liability for death or *
-* personal injury resulting from such party's negligence to the *
-* extent applicable law prohibits such limitation. Some *
-* jurisdictions do not allow the exclusion or limitation of *
-* incidental or consequential damages, so this exclusion and *
-* limitation may not apply to You. *
-* *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
- This Source Code Form is "Incompatible With Secondary Licenses", as
- defined by the Mozilla Public License, v. 2.0.
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md
deleted file mode 100644
index 706b7ef2e..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md
+++ /dev/null
@@ -1,386 +0,0 @@
-# Go-MySQL-Driver
-
-A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package
-
-![Go-MySQL-Driver logo](https://raw.github.com/wiki/go-sql-driver/mysql/gomysql_m.png "Golang Gopher holding the MySQL Dolphin")
-
-**Latest stable Release:** [Version 1.2 (June 03, 2014)](https://github.com/go-sql-driver/mysql/releases)
-
-[![Build Status](https://travis-ci.org/go-sql-driver/mysql.png?branch=master)](https://travis-ci.org/go-sql-driver/mysql)
-
----------------------------------------
- * [Features](#features)
- * [Requirements](#requirements)
- * [Installation](#installation)
- * [Usage](#usage)
- * [DSN (Data Source Name)](#dsn-data-source-name)
- * [Password](#password)
- * [Protocol](#protocol)
- * [Address](#address)
- * [Parameters](#parameters)
- * [Examples](#examples)
- * [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
- * [time.Time support](#timetime-support)
- * [Unicode support](#unicode-support)
- * [Testing / Development](#testing--development)
- * [License](#license)
-
----------------------------------------
-
-## Features
- * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")
- * Native Go implementation. No C-bindings, just pure Go
- * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](http://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
- * Automatic handling of broken connections
- * Automatic Connection Pooling *(by database/sql package)*
- * Supports queries larger than 16MB
- * Full [`sql.RawBytes`](http://golang.org/pkg/database/sql/#RawBytes) support.
- * Intelligent `LONG DATA` handling in prepared statements
- * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support
- * Optional `time.Time` parsing
- * Optional placeholder interpolation
-
-## Requirements
- * Go 1.2 or higher
- * MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
-
----------------------------------------
-
-## Installation
-Simple install the package to your [$GOPATH](http://code.google.com/p/go-wiki/wiki/GOPATH "GOPATH") with the [go tool](http://golang.org/cmd/go/ "go command") from shell:
-```bash
-$ go get github.com/go-sql-driver/mysql
-```
-Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`.
-
-## Usage
-_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](http://golang.org/pkg/database/sql) API then.
-
-Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:
-```go
-import "database/sql"
-import _ "github.com/go-sql-driver/mysql"
-
-db, err := sql.Open("mysql", "user:password@/dbname")
-```
-
-[Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples").
-
-
-### DSN (Data Source Name)
-
-The Data Source Name has a common format, like e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php) uses it, but without type-prefix (optional parts marked by squared brackets):
-```
-[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
-```
-
-A DSN in its fullest form:
-```
-username:password@protocol(address)/dbname?param=value
-```
-
-Except for the databasename, all values are optional. So the minimal DSN is:
-```
-/dbname
-```
-
-If you do not want to preselect a database, leave `dbname` empty:
-```
-/
-```
-This has the same effect as an empty DSN string:
-```
-
-```
-
-#### Password
-Passwords can consist of any character. Escaping is **not** necessary.
-
-#### Protocol
-See [net.Dial](http://golang.org/pkg/net/#Dial) for more information which networks are available.
-In general you should use an Unix domain socket if available and TCP otherwise for best performance.
-
-#### Address
-For TCP and UDP networks, addresses have the form `host:port`.
-If `host` is a literal IPv6 address, it must be enclosed in square brackets.
-The functions [net.JoinHostPort](http://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](http://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
-
-For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`.
-
-#### Parameters
-*Parameters are case-sensitive!*
-
-Notice that any of `true`, `TRUE`, `True` or `1` is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: `false`, `FALSE`, `False` or `0`.
-
-##### `allowAllFiles`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-`allowAllFiles=true` disables the file Whitelist for `LOAD DATA LOCAL INFILE` and allows *all* files.
-[*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)
-
-##### `allowCleartextPasswords`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-`allowCleartextPasswords=true` allows using the [cleartext client side plugin](http://dev.mysql.com/doc/en/cleartext-authentication-plugin.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network.
-
-##### `allowOldPasswords`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-`allowOldPasswords=true` allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also [the old_passwords wiki page](https://github.com/go-sql-driver/mysql/wiki/old_passwords).
-
-##### `charset`
-
-```
-Type: string
-Valid Values: <name>
-Default: none
-```
-
-Sets the charset used for client-server interaction (`"SET NAMES <value>"`). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset failes. This enables for example support for `utf8mb4` ([introduced in MySQL 5.5.3](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)) with fallback to `utf8` for older servers (`charset=utf8mb4,utf8`).
-
-Usage of the `charset` parameter is discouraged because it issues additional queries to the server.
-Unless you need the fallback behavior, please use `collation` instead.
-
-##### `collation`
-
-```
-Type: string
-Valid Values: <name>
-Default: utf8_general_ci
-```
-
-Sets the collation used for client-server interaction on connection. In contrast to `charset`, `collation` does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.
-
-A list of valid charsets for a server is retrievable with `SHOW COLLATION`.
-
-##### `clientFoundRows`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed.
-
-##### `columnsWithAlias`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example:
-
-```
-SELECT u.id FROM users as u
-```
-
-will return `u.id` instead of just `id` if `columnsWithAlias=true`.
-
-##### `interpolateParams`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`.
-
-*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are blacklisted as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!*
-
-##### `loc`
-
-```
-Type: string
-Valid Values: <escaped name>
-Default: UTC
-```
-
-Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details.
-
-Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
-
-Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
-
-
-##### `parseTime`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
-
-
-##### `strict`
-
-```
-Type: bool
-Valid Values: true, false
-Default: false
-```
-
-`strict=true` enables the strict mode in which MySQL warnings are treated as errors.
-
-By default MySQL also treats notes as warnings. Use [`sql_notes=false`](http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sql_notes) to ignore notes. See the [examples](#examples) for an DSN example.
-
-
-##### `timeout`
-
-```
-Type: decimal number
-Default: OS default
-```
-
-*Driver* side connection timeout. The value must be a string of decimal numbers, each with optional fraction and a unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*. To set a server side timeout, use the parameter [`wait_timeout`](http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout).
-
-
-##### `tls`
-
-```
-Type: bool / string
-Valid Values: true, false, skip-verify, <name>
-Default: false
-```
-
-`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
-
-
-##### System Variables
-
-All other parameters are interpreted as system variables:
- * `autocommit`: `"SET autocommit=<value>"`
- * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone=<value>"`
- * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"`
- * `param`: `"SET <param>=<value>"`
-
-*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!*
-
-#### Examples
-```
-user@unix(/path/to/socket)/dbname
-```
-
-```
-root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
-```
-
-```
-user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
-```
-
-Use the [strict mode](#strict) but ignore notes:
-```
-user:password@/dbname?strict=true&sql_notes=false
-```
-
-TCP via IPv6:
-```
-user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci
-```
-
-TCP on a remote host, e.g. Amazon RDS:
-```
-id:password@tcp(your-amazonaws-uri.com:3306)/dbname
-```
-
-Google Cloud SQL on App Engine:
-```
-user@cloudsql(project-id:instance-name)/dbname
-```
-
-TCP using default port (3306) on localhost:
-```
-user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
-```
-
-Use the default protocol (tcp) and host (localhost:3306):
-```
-user:password@/dbname
-```
-
-No Database preselected:
-```
-user:password@/
-```
-
-### `LOAD DATA LOCAL INFILE` support
-For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
-```go
-import "github.com/go-sql-driver/mysql"
-```
-
-Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)).
-
-To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore.
-
-See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
-
-
-### `time.Time` support
-The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your programm.
-
-However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](http://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
-
-**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes).
-
-Alternatively you can use the [`NullTime`](http://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
-
-
-### Unicode support
-Since version 1.1 Go-MySQL-Driver automatically uses the collation `utf8_general_ci` by default.
-
-Other collations / charsets can be set using the [`collation`](#collation) DSN parameter.
-
-Version 1.0 of the driver recommended adding `&charset=utf8` (alias for `SET NAMES utf8`) to the DSN to enable proper UTF-8 support. This is not necessary anymore. The [`collation`](#collation) parameter should be preferred to set another collation / charset than the default.
-
-See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
-
-
-## Testing / Development
-To run the driver tests you may need to adjust the configuration. See the [Testing Wiki-Page](https://github.com/go-sql-driver/mysql/wiki/Testing "Testing") for details.
-
-Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated.
-If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls).
-
-See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/CONTRIBUTING.md) for details.
-
----------------------------------------
-
-## License
-Go-MySQL-Driver is licensed under the [Mozilla Public License Version 2.0](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
-
-Mozilla summarizes the license scope as follows:
-> MPL: The copyleft applies to any files containing MPLed code.
-
-
-That means:
- * You can **use** the **unchanged** source code both in private and commercially
- * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0)
- * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**
-
-Please read the [MPL 2.0 FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license.
-
-You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
-
-![Go Gopher and MySQL Dolphin](https://raw.github.com/wiki/go-sql-driver/mysql/go-mysql-driver_m.jpg "Golang Gopher transporting the MySQL Dolphin in a wheelbarrow")
-
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go
deleted file mode 100644
index 565614eef..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// +build appengine
-
-package mysql
-
-import (
- "appengine/cloudsql"
-)
-
-func init() {
- RegisterDial("cloudsql", cloudsql.Dial)
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/buffer.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/buffer.go
deleted file mode 100644
index 509ce89e4..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/buffer.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import "io"
-
-const defaultBufSize = 4096
-
-// A buffer which is used for both reading and writing.
-// This is possible since communication on each connection is synchronous.
-// In other words, we can't write and read simultaneously on the same connection.
-// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
-// Also highly optimized for this particular use case.
-type buffer struct {
- buf []byte
- rd io.Reader
- idx int
- length int
-}
-
-func newBuffer(rd io.Reader) buffer {
- var b [defaultBufSize]byte
- return buffer{
- buf: b[:],
- rd: rd,
- }
-}
-
-// fill reads into the buffer until at least _need_ bytes are in it
-func (b *buffer) fill(need int) error {
- n := b.length
-
- // move existing data to the beginning
- if n > 0 && b.idx > 0 {
- copy(b.buf[0:n], b.buf[b.idx:])
- }
-
- // grow buffer if necessary
- // TODO: let the buffer shrink again at some point
- // Maybe keep the org buf slice and swap back?
- if need > len(b.buf) {
- // Round up to the next multiple of the default size
- newBuf := make([]byte, ((need/defaultBufSize)+1)*defaultBufSize)
- copy(newBuf, b.buf)
- b.buf = newBuf
- }
-
- b.idx = 0
-
- for {
- nn, err := b.rd.Read(b.buf[n:])
- n += nn
-
- switch err {
- case nil:
- if n < need {
- continue
- }
- b.length = n
- return nil
-
- case io.EOF:
- if n >= need {
- b.length = n
- return nil
- }
- return io.ErrUnexpectedEOF
-
- default:
- return err
- }
- }
-}
-
-// returns next N bytes from buffer.
-// The returned slice is only guaranteed to be valid until the next read
-func (b *buffer) readNext(need int) ([]byte, error) {
- if b.length < need {
- // refill
- if err := b.fill(need); err != nil {
- return nil, err
- }
- }
-
- offset := b.idx
- b.idx += need
- b.length -= need
- return b.buf[offset:b.idx], nil
-}
-
-// returns a buffer with the requested size.
-// If possible, a slice from the existing buffer is returned.
-// Otherwise a bigger buffer is made.
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeBuffer(length int) []byte {
- if b.length > 0 {
- return nil
- }
-
- // test (cheap) general case first
- if length <= defaultBufSize || length <= cap(b.buf) {
- return b.buf[:length]
- }
-
- if length < maxPacketSize {
- b.buf = make([]byte, length)
- return b.buf
- }
- return make([]byte, length)
-}
-
-// shortcut which can be used if the requested buffer is guaranteed to be
-// smaller than defaultBufSize
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeSmallBuffer(length int) []byte {
- if b.length == 0 {
- return b.buf[:length]
- }
- return nil
-}
-
-// takeCompleteBuffer returns the complete existing buffer.
-// This can be used if the necessary buffer size is unknown.
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeCompleteBuffer() []byte {
- if b.length == 0 {
- return b.buf
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/collations.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/collations.go
deleted file mode 100644
index 6c1d613d5..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/collations.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2014 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-const defaultCollation byte = 33 // utf8_general_ci
-
-// A list of available collations mapped to the internal ID.
-// To update this map use the following MySQL query:
-// SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS
-var collations = map[string]byte{
- "big5_chinese_ci": 1,
- "latin2_czech_cs": 2,
- "dec8_swedish_ci": 3,
- "cp850_general_ci": 4,
- "latin1_german1_ci": 5,
- "hp8_english_ci": 6,
- "koi8r_general_ci": 7,
- "latin1_swedish_ci": 8,
- "latin2_general_ci": 9,
- "swe7_swedish_ci": 10,
- "ascii_general_ci": 11,
- "ujis_japanese_ci": 12,
- "sjis_japanese_ci": 13,
- "cp1251_bulgarian_ci": 14,
- "latin1_danish_ci": 15,
- "hebrew_general_ci": 16,
- "tis620_thai_ci": 18,
- "euckr_korean_ci": 19,
- "latin7_estonian_cs": 20,
- "latin2_hungarian_ci": 21,
- "koi8u_general_ci": 22,
- "cp1251_ukrainian_ci": 23,
- "gb2312_chinese_ci": 24,
- "greek_general_ci": 25,
- "cp1250_general_ci": 26,
- "latin2_croatian_ci": 27,
- "gbk_chinese_ci": 28,
- "cp1257_lithuanian_ci": 29,
- "latin5_turkish_ci": 30,
- "latin1_german2_ci": 31,
- "armscii8_general_ci": 32,
- "utf8_general_ci": 33,
- "cp1250_czech_cs": 34,
- "ucs2_general_ci": 35,
- "cp866_general_ci": 36,
- "keybcs2_general_ci": 37,
- "macce_general_ci": 38,
- "macroman_general_ci": 39,
- "cp852_general_ci": 40,
- "latin7_general_ci": 41,
- "latin7_general_cs": 42,
- "macce_bin": 43,
- "cp1250_croatian_ci": 44,
- "utf8mb4_general_ci": 45,
- "utf8mb4_bin": 46,
- "latin1_bin": 47,
- "latin1_general_ci": 48,
- "latin1_general_cs": 49,
- "cp1251_bin": 50,
- "cp1251_general_ci": 51,
- "cp1251_general_cs": 52,
- "macroman_bin": 53,
- "utf16_general_ci": 54,
- "utf16_bin": 55,
- "utf16le_general_ci": 56,
- "cp1256_general_ci": 57,
- "cp1257_bin": 58,
- "cp1257_general_ci": 59,
- "utf32_general_ci": 60,
- "utf32_bin": 61,
- "utf16le_bin": 62,
- "binary": 63,
- "armscii8_bin": 64,
- "ascii_bin": 65,
- "cp1250_bin": 66,
- "cp1256_bin": 67,
- "cp866_bin": 68,
- "dec8_bin": 69,
- "greek_bin": 70,
- "hebrew_bin": 71,
- "hp8_bin": 72,
- "keybcs2_bin": 73,
- "koi8r_bin": 74,
- "koi8u_bin": 75,
- "latin2_bin": 77,
- "latin5_bin": 78,
- "latin7_bin": 79,
- "cp850_bin": 80,
- "cp852_bin": 81,
- "swe7_bin": 82,
- "utf8_bin": 83,
- "big5_bin": 84,
- "euckr_bin": 85,
- "gb2312_bin": 86,
- "gbk_bin": 87,
- "sjis_bin": 88,
- "tis620_bin": 89,
- "ucs2_bin": 90,
- "ujis_bin": 91,
- "geostd8_general_ci": 92,
- "geostd8_bin": 93,
- "latin1_spanish_ci": 94,
- "cp932_japanese_ci": 95,
- "cp932_bin": 96,
- "eucjpms_japanese_ci": 97,
- "eucjpms_bin": 98,
- "cp1250_polish_ci": 99,
- "utf16_unicode_ci": 101,
- "utf16_icelandic_ci": 102,
- "utf16_latvian_ci": 103,
- "utf16_romanian_ci": 104,
- "utf16_slovenian_ci": 105,
- "utf16_polish_ci": 106,
- "utf16_estonian_ci": 107,
- "utf16_spanish_ci": 108,
- "utf16_swedish_ci": 109,
- "utf16_turkish_ci": 110,
- "utf16_czech_ci": 111,
- "utf16_danish_ci": 112,
- "utf16_lithuanian_ci": 113,
- "utf16_slovak_ci": 114,
- "utf16_spanish2_ci": 115,
- "utf16_roman_ci": 116,
- "utf16_persian_ci": 117,
- "utf16_esperanto_ci": 118,
- "utf16_hungarian_ci": 119,
- "utf16_sinhala_ci": 120,
- "utf16_german2_ci": 121,
- "utf16_croatian_ci": 122,
- "utf16_unicode_520_ci": 123,
- "utf16_vietnamese_ci": 124,
- "ucs2_unicode_ci": 128,
- "ucs2_icelandic_ci": 129,
- "ucs2_latvian_ci": 130,
- "ucs2_romanian_ci": 131,
- "ucs2_slovenian_ci": 132,
- "ucs2_polish_ci": 133,
- "ucs2_estonian_ci": 134,
- "ucs2_spanish_ci": 135,
- "ucs2_swedish_ci": 136,
- "ucs2_turkish_ci": 137,
- "ucs2_czech_ci": 138,
- "ucs2_danish_ci": 139,
- "ucs2_lithuanian_ci": 140,
- "ucs2_slovak_ci": 141,
- "ucs2_spanish2_ci": 142,
- "ucs2_roman_ci": 143,
- "ucs2_persian_ci": 144,
- "ucs2_esperanto_ci": 145,
- "ucs2_hungarian_ci": 146,
- "ucs2_sinhala_ci": 147,
- "ucs2_german2_ci": 148,
- "ucs2_croatian_ci": 149,
- "ucs2_unicode_520_ci": 150,
- "ucs2_vietnamese_ci": 151,
- "ucs2_general_mysql500_ci": 159,
- "utf32_unicode_ci": 160,
- "utf32_icelandic_ci": 161,
- "utf32_latvian_ci": 162,
- "utf32_romanian_ci": 163,
- "utf32_slovenian_ci": 164,
- "utf32_polish_ci": 165,
- "utf32_estonian_ci": 166,
- "utf32_spanish_ci": 167,
- "utf32_swedish_ci": 168,
- "utf32_turkish_ci": 169,
- "utf32_czech_ci": 170,
- "utf32_danish_ci": 171,
- "utf32_lithuanian_ci": 172,
- "utf32_slovak_ci": 173,
- "utf32_spanish2_ci": 174,
- "utf32_roman_ci": 175,
- "utf32_persian_ci": 176,
- "utf32_esperanto_ci": 177,
- "utf32_hungarian_ci": 178,
- "utf32_sinhala_ci": 179,
- "utf32_german2_ci": 180,
- "utf32_croatian_ci": 181,
- "utf32_unicode_520_ci": 182,
- "utf32_vietnamese_ci": 183,
- "utf8_unicode_ci": 192,
- "utf8_icelandic_ci": 193,
- "utf8_latvian_ci": 194,
- "utf8_romanian_ci": 195,
- "utf8_slovenian_ci": 196,
- "utf8_polish_ci": 197,
- "utf8_estonian_ci": 198,
- "utf8_spanish_ci": 199,
- "utf8_swedish_ci": 200,
- "utf8_turkish_ci": 201,
- "utf8_czech_ci": 202,
- "utf8_danish_ci": 203,
- "utf8_lithuanian_ci": 204,
- "utf8_slovak_ci": 205,
- "utf8_spanish2_ci": 206,
- "utf8_roman_ci": 207,
- "utf8_persian_ci": 208,
- "utf8_esperanto_ci": 209,
- "utf8_hungarian_ci": 210,
- "utf8_sinhala_ci": 211,
- "utf8_german2_ci": 212,
- "utf8_croatian_ci": 213,
- "utf8_unicode_520_ci": 214,
- "utf8_vietnamese_ci": 215,
- "utf8_general_mysql500_ci": 223,
- "utf8mb4_unicode_ci": 224,
- "utf8mb4_icelandic_ci": 225,
- "utf8mb4_latvian_ci": 226,
- "utf8mb4_romanian_ci": 227,
- "utf8mb4_slovenian_ci": 228,
- "utf8mb4_polish_ci": 229,
- "utf8mb4_estonian_ci": 230,
- "utf8mb4_spanish_ci": 231,
- "utf8mb4_swedish_ci": 232,
- "utf8mb4_turkish_ci": 233,
- "utf8mb4_czech_ci": 234,
- "utf8mb4_danish_ci": 235,
- "utf8mb4_lithuanian_ci": 236,
- "utf8mb4_slovak_ci": 237,
- "utf8mb4_spanish2_ci": 238,
- "utf8mb4_roman_ci": 239,
- "utf8mb4_persian_ci": 240,
- "utf8mb4_esperanto_ci": 241,
- "utf8mb4_hungarian_ci": 242,
- "utf8mb4_sinhala_ci": 243,
- "utf8mb4_german2_ci": 244,
- "utf8mb4_croatian_ci": 245,
- "utf8mb4_unicode_520_ci": 246,
- "utf8mb4_vietnamese_ci": 247,
-}
-
-// A blacklist of collations which is unsafe to interpolate parameters.
-// These multibyte encodings may contains 0x5c (`\`) in their trailing bytes.
-var unsafeCollations = map[byte]bool{
- 1: true, // big5_chinese_ci
- 13: true, // sjis_japanese_ci
- 28: true, // gbk_chinese_ci
- 84: true, // big5_bin
- 86: true, // gb2312_bin
- 87: true, // gbk_bin
- 88: true, // sjis_bin
- 95: true, // cp932_japanese_ci
- 96: true, // cp932_bin
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/connection.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/connection.go
deleted file mode 100644
index 72ed09d69..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/connection.go
+++ /dev/null
@@ -1,403 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "crypto/tls"
- "database/sql/driver"
- "errors"
- "net"
- "strconv"
- "strings"
- "time"
-)
-
-type mysqlConn struct {
- buf buffer
- netConn net.Conn
- affectedRows uint64
- insertId uint64
- cfg *config
- maxPacketAllowed int
- maxWriteSize int
- flags clientFlag
- status statusFlag
- sequence uint8
- parseTime bool
- strict bool
-}
-
-type config struct {
- user string
- passwd string
- net string
- addr string
- dbname string
- params map[string]string
- loc *time.Location
- tls *tls.Config
- timeout time.Duration
- collation uint8
- allowAllFiles bool
- allowOldPasswords bool
- allowCleartextPasswords bool
- clientFoundRows bool
- columnsWithAlias bool
- interpolateParams bool
-}
-
-// Handles parameters set in DSN after the connection is established
-func (mc *mysqlConn) handleParams() (err error) {
- for param, val := range mc.cfg.params {
- switch param {
- // Charset
- case "charset":
- charsets := strings.Split(val, ",")
- for i := range charsets {
- // ignore errors here - a charset may not exist
- err = mc.exec("SET NAMES " + charsets[i])
- if err == nil {
- break
- }
- }
- if err != nil {
- return
- }
-
- // time.Time parsing
- case "parseTime":
- var isBool bool
- mc.parseTime, isBool = readBool(val)
- if !isBool {
- return errors.New("Invalid Bool value: " + val)
- }
-
- // Strict mode
- case "strict":
- var isBool bool
- mc.strict, isBool = readBool(val)
- if !isBool {
- return errors.New("Invalid Bool value: " + val)
- }
-
- // Compression
- case "compress":
- err = errors.New("Compression not implemented yet")
- return
-
- // System Vars
- default:
- err = mc.exec("SET " + param + "=" + val + "")
- if err != nil {
- return
- }
- }
- }
-
- return
-}
-
-func (mc *mysqlConn) Begin() (driver.Tx, error) {
- if mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- err := mc.exec("START TRANSACTION")
- if err == nil {
- return &mysqlTx{mc}, err
- }
-
- return nil, err
-}
-
-func (mc *mysqlConn) Close() (err error) {
- // Makes Close idempotent
- if mc.netConn != nil {
- err = mc.writeCommandPacket(comQuit)
- if err == nil {
- err = mc.netConn.Close()
- } else {
- mc.netConn.Close()
- }
- mc.netConn = nil
- }
-
- mc.cfg = nil
- mc.buf.rd = nil
-
- return
-}
-
-func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
- if mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- // Send command
- err := mc.writeCommandPacketStr(comStmtPrepare, query)
- if err != nil {
- return nil, err
- }
-
- stmt := &mysqlStmt{
- mc: mc,
- }
-
- // Read Result
- columnCount, err := stmt.readPrepareResultPacket()
- if err == nil {
- if stmt.paramCount > 0 {
- if err = mc.readUntilEOF(); err != nil {
- return nil, err
- }
- }
-
- if columnCount > 0 {
- err = mc.readUntilEOF()
- }
- }
-
- return stmt, err
-}
-
-func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
- buf := mc.buf.takeCompleteBuffer()
- if buf == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return "", driver.ErrBadConn
- }
- buf = buf[:0]
- argPos := 0
-
- for i := 0; i < len(query); i++ {
- q := strings.IndexByte(query[i:], '?')
- if q == -1 {
- buf = append(buf, query[i:]...)
- break
- }
- buf = append(buf, query[i:i+q]...)
- i += q
-
- arg := args[argPos]
- argPos++
-
- if arg == nil {
- buf = append(buf, "NULL"...)
- continue
- }
-
- switch v := arg.(type) {
- case int64:
- buf = strconv.AppendInt(buf, v, 10)
- case float64:
- buf = strconv.AppendFloat(buf, v, 'g', -1, 64)
- case bool:
- if v {
- buf = append(buf, '1')
- } else {
- buf = append(buf, '0')
- }
- case time.Time:
- if v.IsZero() {
- buf = append(buf, "'0000-00-00'"...)
- } else {
- v := v.In(mc.cfg.loc)
- v = v.Add(time.Nanosecond * 500) // To round under microsecond
- year := v.Year()
- year100 := year / 100
- year1 := year % 100
- month := v.Month()
- day := v.Day()
- hour := v.Hour()
- minute := v.Minute()
- second := v.Second()
- micro := v.Nanosecond() / 1000
-
- buf = append(buf, []byte{
- '\'',
- digits10[year100], digits01[year100],
- digits10[year1], digits01[year1],
- '-',
- digits10[month], digits01[month],
- '-',
- digits10[day], digits01[day],
- ' ',
- digits10[hour], digits01[hour],
- ':',
- digits10[minute], digits01[minute],
- ':',
- digits10[second], digits01[second],
- }...)
-
- if micro != 0 {
- micro10000 := micro / 10000
- micro100 := micro / 100 % 100
- micro1 := micro % 100
- buf = append(buf, []byte{
- '.',
- digits10[micro10000], digits01[micro10000],
- digits10[micro100], digits01[micro100],
- digits10[micro1], digits01[micro1],
- }...)
- }
- buf = append(buf, '\'')
- }
- case []byte:
- if v == nil {
- buf = append(buf, "NULL"...)
- } else {
- buf = append(buf, "_binary'"...)
- if mc.status&statusNoBackslashEscapes == 0 {
- buf = escapeBytesBackslash(buf, v)
- } else {
- buf = escapeBytesQuotes(buf, v)
- }
- buf = append(buf, '\'')
- }
- case string:
- buf = append(buf, '\'')
- if mc.status&statusNoBackslashEscapes == 0 {
- buf = escapeStringBackslash(buf, v)
- } else {
- buf = escapeStringQuotes(buf, v)
- }
- buf = append(buf, '\'')
- default:
- return "", driver.ErrSkip
- }
-
- if len(buf)+4 > mc.maxPacketAllowed {
- return "", driver.ErrSkip
- }
- }
- if argPos != len(args) {
- return "", driver.ErrSkip
- }
- return string(buf), nil
-}
-
-func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
- if mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- if len(args) != 0 {
- if !mc.cfg.interpolateParams {
- return nil, driver.ErrSkip
- }
- // try to interpolate the parameters to save extra roundtrips for preparing and closing a statement
- prepared, err := mc.interpolateParams(query, args)
- if err != nil {
- return nil, err
- }
- query = prepared
- args = nil
- }
- mc.affectedRows = 0
- mc.insertId = 0
-
- err := mc.exec(query)
- if err == nil {
- return &mysqlResult{
- affectedRows: int64(mc.affectedRows),
- insertId: int64(mc.insertId),
- }, err
- }
- return nil, err
-}
-
-// Internal function to execute commands
-func (mc *mysqlConn) exec(query string) error {
- // Send command
- err := mc.writeCommandPacketStr(comQuery, query)
- if err != nil {
- return err
- }
-
- // Read Result
- resLen, err := mc.readResultSetHeaderPacket()
- if err == nil && resLen > 0 {
- if err = mc.readUntilEOF(); err != nil {
- return err
- }
-
- err = mc.readUntilEOF()
- }
-
- return err
-}
-
-func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
- if mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- if len(args) != 0 {
- if !mc.cfg.interpolateParams {
- return nil, driver.ErrSkip
- }
- // try client-side prepare to reduce roundtrip
- prepared, err := mc.interpolateParams(query, args)
- if err != nil {
- return nil, err
- }
- query = prepared
- args = nil
- }
- // Send command
- err := mc.writeCommandPacketStr(comQuery, query)
- if err == nil {
- // Read Result
- var resLen int
- resLen, err = mc.readResultSetHeaderPacket()
- if err == nil {
- rows := new(textRows)
- rows.mc = mc
-
- if resLen == 0 {
- // no columns, no more data
- return emptyRows{}, nil
- }
- // Columns
- rows.columns, err = mc.readColumns(resLen)
- return rows, err
- }
- }
- return nil, err
-}
-
-// Gets the value of the given MySQL System Variable
-// The returned byte slice is only valid until the next read
-func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
- // Send command
- if err := mc.writeCommandPacketStr(comQuery, "SELECT @@"+name); err != nil {
- return nil, err
- }
-
- // Read Result
- resLen, err := mc.readResultSetHeaderPacket()
- if err == nil {
- rows := new(textRows)
- rows.mc = mc
-
- if resLen > 0 {
- // Columns
- if err := mc.readUntilEOF(); err != nil {
- return nil, err
- }
- }
-
- dest := make([]driver.Value, resLen)
- if err = rows.readRow(dest); err == nil {
- return dest[0].([]byte), mc.readUntilEOF()
- }
- }
- return nil, err
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/const.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/const.go
deleted file mode 100644
index dddc12908..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/const.go
+++ /dev/null
@@ -1,162 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-const (
- minProtocolVersion byte = 10
- maxPacketSize = 1<<24 - 1
- timeFormat = "2006-01-02 15:04:05.999999"
-)
-
-// MySQL constants documentation:
-// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
-
-const (
- iOK byte = 0x00
- iLocalInFile byte = 0xfb
- iEOF byte = 0xfe
- iERR byte = 0xff
-)
-
-// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
-type clientFlag uint32
-
-const (
- clientLongPassword clientFlag = 1 << iota
- clientFoundRows
- clientLongFlag
- clientConnectWithDB
- clientNoSchema
- clientCompress
- clientODBC
- clientLocalFiles
- clientIgnoreSpace
- clientProtocol41
- clientInteractive
- clientSSL
- clientIgnoreSIGPIPE
- clientTransactions
- clientReserved
- clientSecureConn
- clientMultiStatements
- clientMultiResults
- clientPSMultiResults
- clientPluginAuth
- clientConnectAttrs
- clientPluginAuthLenEncClientData
- clientCanHandleExpiredPasswords
- clientSessionTrack
- clientDeprecateEOF
-)
-
-const (
- comQuit byte = iota + 1
- comInitDB
- comQuery
- comFieldList
- comCreateDB
- comDropDB
- comRefresh
- comShutdown
- comStatistics
- comProcessInfo
- comConnect
- comProcessKill
- comDebug
- comPing
- comTime
- comDelayedInsert
- comChangeUser
- comBinlogDump
- comTableDump
- comConnectOut
- comRegisterSlave
- comStmtPrepare
- comStmtExecute
- comStmtSendLongData
- comStmtClose
- comStmtReset
- comSetOption
- comStmtFetch
-)
-
-// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType
-const (
- fieldTypeDecimal byte = iota
- fieldTypeTiny
- fieldTypeShort
- fieldTypeLong
- fieldTypeFloat
- fieldTypeDouble
- fieldTypeNULL
- fieldTypeTimestamp
- fieldTypeLongLong
- fieldTypeInt24
- fieldTypeDate
- fieldTypeTime
- fieldTypeDateTime
- fieldTypeYear
- fieldTypeNewDate
- fieldTypeVarChar
- fieldTypeBit
-)
-const (
- fieldTypeNewDecimal byte = iota + 0xf6
- fieldTypeEnum
- fieldTypeSet
- fieldTypeTinyBLOB
- fieldTypeMediumBLOB
- fieldTypeLongBLOB
- fieldTypeBLOB
- fieldTypeVarString
- fieldTypeString
- fieldTypeGeometry
-)
-
-type fieldFlag uint16
-
-const (
- flagNotNULL fieldFlag = 1 << iota
- flagPriKey
- flagUniqueKey
- flagMultipleKey
- flagBLOB
- flagUnsigned
- flagZeroFill
- flagBinary
- flagEnum
- flagAutoIncrement
- flagTimestamp
- flagSet
- flagUnknown1
- flagUnknown2
- flagUnknown3
- flagUnknown4
-)
-
-// http://dev.mysql.com/doc/internals/en/status-flags.html
-type statusFlag uint16
-
-const (
- statusInTrans statusFlag = 1 << iota
- statusInAutocommit
- statusReserved // Not in documentation
- statusMoreResultsExists
- statusNoGoodIndexUsed
- statusNoIndexUsed
- statusCursorExists
- statusLastRowSent
- statusDbDropped
- statusNoBackslashEscapes
- statusMetadataChanged
- statusQueryWasSlow
- statusPsOutParams
- statusInTransReadonly
- statusSessionStateChanged
-)
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/driver.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/driver.go
deleted file mode 100644
index d310624ad..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/driver.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// The driver should be used via the database/sql package:
-//
-// import "database/sql"
-// import _ "github.com/go-sql-driver/mysql"
-//
-// db, err := sql.Open("mysql", "user:password@/dbname")
-//
-// See https://github.com/go-sql-driver/mysql#usage for details
-package mysql
-
-import (
- "database/sql"
- "database/sql/driver"
- "net"
-)
-
-// This struct is exported to make the driver directly accessible.
-// In general the driver is used via the database/sql package.
-type MySQLDriver struct{}
-
-// DialFunc is a function which can be used to establish the network connection.
-// Custom dial functions must be registered with RegisterDial
-type DialFunc func(addr string) (net.Conn, error)
-
-var dials map[string]DialFunc
-
-// RegisterDial registers a custom dial function. It can then be used by the
-// network address mynet(addr), where mynet is the registered new network.
-// addr is passed as a parameter to the dial function.
-func RegisterDial(net string, dial DialFunc) {
- if dials == nil {
- dials = make(map[string]DialFunc)
- }
- dials[net] = dial
-}
-
-// Open new Connection.
-// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
-// the DSN string is formated
-func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
- var err error
-
- // New mysqlConn
- mc := &mysqlConn{
- maxPacketAllowed: maxPacketSize,
- maxWriteSize: maxPacketSize - 1,
- }
- mc.cfg, err = parseDSN(dsn)
- if err != nil {
- return nil, err
- }
-
- // Connect to Server
- if dial, ok := dials[mc.cfg.net]; ok {
- mc.netConn, err = dial(mc.cfg.addr)
- } else {
- nd := net.Dialer{Timeout: mc.cfg.timeout}
- mc.netConn, err = nd.Dial(mc.cfg.net, mc.cfg.addr)
- }
- if err != nil {
- return nil, err
- }
-
- // Enable TCP Keepalives on TCP connections
- if tc, ok := mc.netConn.(*net.TCPConn); ok {
- if err := tc.SetKeepAlive(true); err != nil {
- // Don't send COM_QUIT before handshake.
- mc.netConn.Close()
- mc.netConn = nil
- return nil, err
- }
- }
-
- mc.buf = newBuffer(mc.netConn)
-
- // Reading Handshake Initialization Packet
- cipher, err := mc.readInitPacket()
- if err != nil {
- mc.Close()
- return nil, err
- }
-
- // Send Client Authentication Packet
- if err = mc.writeAuthPacket(cipher); err != nil {
- mc.Close()
- return nil, err
- }
-
- // Read Result Packet
- err = mc.readResultOK()
- if err != nil {
- // Retry with old authentication method, if allowed
- if mc.cfg != nil && mc.cfg.allowOldPasswords && err == ErrOldPassword {
- if err = mc.writeOldAuthPacket(cipher); err != nil {
- mc.Close()
- return nil, err
- }
- if err = mc.readResultOK(); err != nil {
- mc.Close()
- return nil, err
- }
- } else if mc.cfg != nil && mc.cfg.allowCleartextPasswords && err == ErrCleartextPassword {
- if err = mc.writeClearAuthPacket(); err != nil {
- mc.Close()
- return nil, err
- }
- if err = mc.readResultOK(); err != nil {
- mc.Close()
- return nil, err
- }
- } else {
- mc.Close()
- return nil, err
- }
-
- }
-
- // Get max allowed packet size
- maxap, err := mc.getSystemVar("max_allowed_packet")
- if err != nil {
- mc.Close()
- return nil, err
- }
- mc.maxPacketAllowed = stringToInt(maxap) - 1
- if mc.maxPacketAllowed < maxPacketSize {
- mc.maxWriteSize = mc.maxPacketAllowed
- }
-
- // Handle DSN Params
- err = mc.handleParams()
- if err != nil {
- mc.Close()
- return nil, err
- }
-
- return mc, nil
-}
-
-func init() {
- sql.Register("mysql", &MySQLDriver{})
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/errors.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/errors.go
deleted file mode 100644
index 44cf30db6..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/errors.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "database/sql/driver"
- "errors"
- "fmt"
- "io"
- "log"
- "os"
-)
-
-// Various errors the driver might return. Can change between driver versions.
-var (
- ErrInvalidConn = errors.New("Invalid Connection")
- ErrMalformPkt = errors.New("Malformed Packet")
- ErrNoTLS = errors.New("TLS encryption requested but server does not support TLS")
- ErrOldPassword = errors.New("This user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")
- ErrCleartextPassword = errors.New("This user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN.")
- ErrUnknownPlugin = errors.New("The authentication plugin is not supported.")
- ErrOldProtocol = errors.New("MySQL-Server does not support required Protocol 41+")
- ErrPktSync = errors.New("Commands out of sync. You can't run this command now")
- ErrPktSyncMul = errors.New("Commands out of sync. Did you run multiple statements at once?")
- ErrPktTooLarge = errors.New("Packet for query is too large. You can change this value on the server by adjusting the 'max_allowed_packet' variable.")
- ErrBusyBuffer = errors.New("Busy buffer")
-)
-
-var errLog Logger = log.New(os.Stderr, "[MySQL] ", log.Ldate|log.Ltime|log.Lshortfile)
-
-// Logger is used to log critical error messages.
-type Logger interface {
- Print(v ...interface{})
-}
-
-// SetLogger is used to set the logger for critical errors.
-// The initial logger is os.Stderr.
-func SetLogger(logger Logger) error {
- if logger == nil {
- return errors.New("logger is nil")
- }
- errLog = logger
- return nil
-}
-
-// MySQLError is an error type which represents a single MySQL error
-type MySQLError struct {
- Number uint16
- Message string
-}
-
-func (me *MySQLError) Error() string {
- return fmt.Sprintf("Error %d: %s", me.Number, me.Message)
-}
-
-// MySQLWarnings is an error type which represents a group of one or more MySQL
-// warnings
-type MySQLWarnings []MySQLWarning
-
-func (mws MySQLWarnings) Error() string {
- var msg string
- for i, warning := range mws {
- if i > 0 {
- msg += "\r\n"
- }
- msg += fmt.Sprintf(
- "%s %s: %s",
- warning.Level,
- warning.Code,
- warning.Message,
- )
- }
- return msg
-}
-
-// MySQLWarning is an error type which represents a single MySQL warning.
-// Warnings are returned in groups only. See MySQLWarnings
-type MySQLWarning struct {
- Level string
- Code string
- Message string
-}
-
-func (mc *mysqlConn) getWarnings() (err error) {
- rows, err := mc.Query("SHOW WARNINGS", nil)
- if err != nil {
- return
- }
-
- var warnings = MySQLWarnings{}
- var values = make([]driver.Value, 3)
-
- for {
- err = rows.Next(values)
- switch err {
- case nil:
- warning := MySQLWarning{}
-
- if raw, ok := values[0].([]byte); ok {
- warning.Level = string(raw)
- } else {
- warning.Level = fmt.Sprintf("%s", values[0])
- }
- if raw, ok := values[1].([]byte); ok {
- warning.Code = string(raw)
- } else {
- warning.Code = fmt.Sprintf("%s", values[1])
- }
- if raw, ok := values[2].([]byte); ok {
- warning.Message = string(raw)
- } else {
- warning.Message = fmt.Sprintf("%s", values[0])
- }
-
- warnings = append(warnings, warning)
-
- case io.EOF:
- return warnings
-
- default:
- rows.Close()
- return
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/infile.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/infile.go
deleted file mode 100644
index 84c53a99c..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/infile.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "fmt"
- "io"
- "os"
- "strings"
- "sync"
-)
-
-var (
- fileRegister map[string]bool
- fileRegisterLock sync.RWMutex
- readerRegister map[string]func() io.Reader
- readerRegisterLock sync.RWMutex
-)
-
-// RegisterLocalFile adds the given file to the file whitelist,
-// so that it can be used by "LOAD DATA LOCAL INFILE <filepath>".
-// Alternatively you can allow the use of all local files with
-// the DSN parameter 'allowAllFiles=true'
-//
-// filePath := "/home/gopher/data.csv"
-// mysql.RegisterLocalFile(filePath)
-// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo")
-// if err != nil {
-// ...
-//
-func RegisterLocalFile(filePath string) {
- fileRegisterLock.Lock()
- // lazy map init
- if fileRegister == nil {
- fileRegister = make(map[string]bool)
- }
-
- fileRegister[strings.Trim(filePath, `"`)] = true
- fileRegisterLock.Unlock()
-}
-
-// DeregisterLocalFile removes the given filepath from the whitelist.
-func DeregisterLocalFile(filePath string) {
- fileRegisterLock.Lock()
- delete(fileRegister, strings.Trim(filePath, `"`))
- fileRegisterLock.Unlock()
-}
-
-// RegisterReaderHandler registers a handler function which is used
-// to receive a io.Reader.
-// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::<name>".
-// If the handler returns a io.ReadCloser Close() is called when the
-// request is finished.
-//
-// mysql.RegisterReaderHandler("data", func() io.Reader {
-// var csvReader io.Reader // Some Reader that returns CSV data
-// ... // Open Reader here
-// return csvReader
-// })
-// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo")
-// if err != nil {
-// ...
-//
-func RegisterReaderHandler(name string, handler func() io.Reader) {
- readerRegisterLock.Lock()
- // lazy map init
- if readerRegister == nil {
- readerRegister = make(map[string]func() io.Reader)
- }
-
- readerRegister[name] = handler
- readerRegisterLock.Unlock()
-}
-
-// DeregisterReaderHandler removes the ReaderHandler function with
-// the given name from the registry.
-func DeregisterReaderHandler(name string) {
- readerRegisterLock.Lock()
- delete(readerRegister, name)
- readerRegisterLock.Unlock()
-}
-
-func deferredClose(err *error, closer io.Closer) {
- closeErr := closer.Close()
- if *err == nil {
- *err = closeErr
- }
-}
-
-func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
- var rdr io.Reader
- var data []byte
-
- if idx := strings.Index(name, "Reader::"); idx == 0 || (idx > 0 && name[idx-1] == '/') { // io.Reader
- // The server might return an an absolute path. See issue #355.
- name = name[idx+8:]
-
- readerRegisterLock.RLock()
- handler, inMap := readerRegister[name]
- readerRegisterLock.RUnlock()
-
- if inMap {
- rdr = handler()
- if rdr != nil {
- data = make([]byte, 4+mc.maxWriteSize)
-
- if cl, ok := rdr.(io.Closer); ok {
- defer deferredClose(&err, cl)
- }
- } else {
- err = fmt.Errorf("Reader '%s' is <nil>", name)
- }
- } else {
- err = fmt.Errorf("Reader '%s' is not registered", name)
- }
- } else { // File
- name = strings.Trim(name, `"`)
- fileRegisterLock.RLock()
- fr := fileRegister[name]
- fileRegisterLock.RUnlock()
- if mc.cfg.allowAllFiles || fr {
- var file *os.File
- var fi os.FileInfo
-
- if file, err = os.Open(name); err == nil {
- defer deferredClose(&err, file)
-
- // get file size
- if fi, err = file.Stat(); err == nil {
- rdr = file
- if fileSize := int(fi.Size()); fileSize <= mc.maxWriteSize {
- data = make([]byte, 4+fileSize)
- } else if fileSize <= mc.maxPacketAllowed {
- data = make([]byte, 4+mc.maxWriteSize)
- } else {
- err = fmt.Errorf("Local File '%s' too large: Size: %d, Max: %d", name, fileSize, mc.maxPacketAllowed)
- }
- }
- }
- } else {
- err = fmt.Errorf("Local File '%s' is not registered. Use the DSN parameter 'allowAllFiles=true' to allow all files", name)
- }
- }
-
- // send content packets
- if err == nil {
- var n int
- for err == nil {
- n, err = rdr.Read(data[4:])
- if n > 0 {
- if ioErr := mc.writePacket(data[:4+n]); ioErr != nil {
- return ioErr
- }
- }
- }
- if err == io.EOF {
- err = nil
- }
- }
-
- // send empty packet (termination)
- if data == nil {
- data = make([]byte, 4)
- }
- if ioErr := mc.writePacket(data[:4]); ioErr != nil {
- return ioErr
- }
-
- // read OK packet
- if err == nil {
- return mc.readResultOK()
- } else {
- mc.readPacket()
- }
- return err
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go
deleted file mode 100644
index 76cb7c84e..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go
+++ /dev/null
@@ -1,1182 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "bytes"
- "crypto/tls"
- "database/sql/driver"
- "encoding/binary"
- "fmt"
- "io"
- "math"
- "time"
-)
-
-// Packets documentation:
-// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
-
-// Read packet to buffer 'data'
-func (mc *mysqlConn) readPacket() ([]byte, error) {
- var payload []byte
- for {
- // Read packet header
- data, err := mc.buf.readNext(4)
- if err != nil {
- errLog.Print(err)
- mc.Close()
- return nil, driver.ErrBadConn
- }
-
- // Packet Length [24 bit]
- pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16)
-
- if pktLen < 1 {
- errLog.Print(ErrMalformPkt)
- mc.Close()
- return nil, driver.ErrBadConn
- }
-
- // Check Packet Sync [8 bit]
- if data[3] != mc.sequence {
- if data[3] > mc.sequence {
- return nil, ErrPktSyncMul
- } else {
- return nil, ErrPktSync
- }
- }
- mc.sequence++
-
- // Read packet body [pktLen bytes]
- data, err = mc.buf.readNext(pktLen)
- if err != nil {
- errLog.Print(err)
- mc.Close()
- return nil, driver.ErrBadConn
- }
-
- isLastPacket := (pktLen < maxPacketSize)
-
- // Zero allocations for non-splitting packets
- if isLastPacket && payload == nil {
- return data, nil
- }
-
- payload = append(payload, data...)
-
- if isLastPacket {
- return payload, nil
- }
- }
-}
-
-// Write packet buffer 'data'
-func (mc *mysqlConn) writePacket(data []byte) error {
- pktLen := len(data) - 4
-
- if pktLen > mc.maxPacketAllowed {
- return ErrPktTooLarge
- }
-
- for {
- var size int
- if pktLen >= maxPacketSize {
- data[0] = 0xff
- data[1] = 0xff
- data[2] = 0xff
- size = maxPacketSize
- } else {
- data[0] = byte(pktLen)
- data[1] = byte(pktLen >> 8)
- data[2] = byte(pktLen >> 16)
- size = pktLen
- }
- data[3] = mc.sequence
-
- // Write packet
- n, err := mc.netConn.Write(data[:4+size])
- if err == nil && n == 4+size {
- mc.sequence++
- if size != maxPacketSize {
- return nil
- }
- pktLen -= size
- data = data[size:]
- continue
- }
-
- // Handle error
- if err == nil { // n != len(data)
- errLog.Print(ErrMalformPkt)
- } else {
- errLog.Print(err)
- }
- return driver.ErrBadConn
- }
-}
-
-/******************************************************************************
-* Initialisation Process *
-******************************************************************************/
-
-// Handshake Initialization Packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
-func (mc *mysqlConn) readInitPacket() ([]byte, error) {
- data, err := mc.readPacket()
- if err != nil {
- return nil, err
- }
-
- if data[0] == iERR {
- return nil, mc.handleErrorPacket(data)
- }
-
- // protocol version [1 byte]
- if data[0] < minProtocolVersion {
- return nil, fmt.Errorf(
- "Unsupported MySQL Protocol Version %d. Protocol Version %d or higher is required",
- data[0],
- minProtocolVersion,
- )
- }
-
- // server version [null terminated string]
- // connection id [4 bytes]
- pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
-
- // first part of the password cipher [8 bytes]
- cipher := data[pos : pos+8]
-
- // (filler) always 0x00 [1 byte]
- pos += 8 + 1
-
- // capability flags (lower 2 bytes) [2 bytes]
- mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
- if mc.flags&clientProtocol41 == 0 {
- return nil, ErrOldProtocol
- }
- if mc.flags&clientSSL == 0 && mc.cfg.tls != nil {
- return nil, ErrNoTLS
- }
- pos += 2
-
- if len(data) > pos {
- // character set [1 byte]
- // status flags [2 bytes]
- // capability flags (upper 2 bytes) [2 bytes]
- // length of auth-plugin-data [1 byte]
- // reserved (all [00]) [10 bytes]
- pos += 1 + 2 + 2 + 1 + 10
-
- // second part of the password cipher [mininum 13 bytes],
- // where len=MAX(13, length of auth-plugin-data - 8)
- //
- // The web documentation is ambiguous about the length. However,
- // according to mysql-5.7/sql/auth/sql_authentication.cc line 538,
- // the 13th byte is "\0 byte, terminating the second part of
- // a scramble". So the second part of the password cipher is
- // a NULL terminated string that's at least 13 bytes with the
- // last byte being NULL.
- //
- // The official Python library uses the fixed length 12
- // which seems to work but technically could have a hidden bug.
- cipher = append(cipher, data[pos:pos+12]...)
-
- // TODO: Verify string termination
- // EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2)
- // \NUL otherwise
- //
- //if data[len(data)-1] == 0 {
- // return
- //}
- //return ErrMalformPkt
-
- // make a memory safe copy of the cipher slice
- var b [20]byte
- copy(b[:], cipher)
- return b[:], nil
- }
-
- // make a memory safe copy of the cipher slice
- var b [8]byte
- copy(b[:], cipher)
- return b[:], nil
-}
-
-// Client Authentication Packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
-func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
- // Adjust client flags based on server support
- clientFlags := clientProtocol41 |
- clientSecureConn |
- clientLongPassword |
- clientTransactions |
- clientLocalFiles |
- clientPluginAuth |
- mc.flags&clientLongFlag
-
- if mc.cfg.clientFoundRows {
- clientFlags |= clientFoundRows
- }
-
- // To enable TLS / SSL
- if mc.cfg.tls != nil {
- clientFlags |= clientSSL
- }
-
- // User Password
- scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.passwd))
-
- pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff) + 21 + 1
-
- // To specify a db name
- if n := len(mc.cfg.dbname); n > 0 {
- clientFlags |= clientConnectWithDB
- pktLen += n + 1
- }
-
- // Calculate packet length and get buffer with that size
- data := mc.buf.takeSmallBuffer(pktLen + 4)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // ClientFlags [32 bit]
- data[4] = byte(clientFlags)
- data[5] = byte(clientFlags >> 8)
- data[6] = byte(clientFlags >> 16)
- data[7] = byte(clientFlags >> 24)
-
- // MaxPacketSize [32 bit] (none)
- data[8] = 0x00
- data[9] = 0x00
- data[10] = 0x00
- data[11] = 0x00
-
- // Charset [1 byte]
- data[12] = mc.cfg.collation
-
- // SSL Connection Request Packet
- // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
- if mc.cfg.tls != nil {
- // Send TLS / SSL request packet
- if err := mc.writePacket(data[:(4+4+1+23)+4]); err != nil {
- return err
- }
-
- // Switch to TLS
- tlsConn := tls.Client(mc.netConn, mc.cfg.tls)
- if err := tlsConn.Handshake(); err != nil {
- return err
- }
- mc.netConn = tlsConn
- mc.buf.rd = tlsConn
- }
-
- // Filler [23 bytes] (all 0x00)
- pos := 13
- for ; pos < 13+23; pos++ {
- data[pos] = 0
- }
-
- // User [null terminated string]
- if len(mc.cfg.user) > 0 {
- pos += copy(data[pos:], mc.cfg.user)
- }
- data[pos] = 0x00
- pos++
-
- // ScrambleBuffer [length encoded integer]
- data[pos] = byte(len(scrambleBuff))
- pos += 1 + copy(data[pos+1:], scrambleBuff)
-
- // Databasename [null terminated string]
- if len(mc.cfg.dbname) > 0 {
- pos += copy(data[pos:], mc.cfg.dbname)
- data[pos] = 0x00
- pos++
- }
-
- // Assume native client during response
- pos += copy(data[pos:], "mysql_native_password")
- data[pos] = 0x00
-
- // Send Auth packet
- return mc.writePacket(data)
-}
-
-// Client old authentication packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
-func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
- // User password
- scrambleBuff := scrambleOldPassword(cipher, []byte(mc.cfg.passwd))
-
- // Calculate the packet length and add a tailing 0
- pktLen := len(scrambleBuff) + 1
- data := mc.buf.takeSmallBuffer(4 + pktLen)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // Add the scrambled password [null terminated string]
- copy(data[4:], scrambleBuff)
- data[4+pktLen-1] = 0x00
-
- return mc.writePacket(data)
-}
-
-// Client clear text authentication packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
-func (mc *mysqlConn) writeClearAuthPacket() error {
- // Calculate the packet length and add a tailing 0
- pktLen := len(mc.cfg.passwd) + 1
- data := mc.buf.takeSmallBuffer(4 + pktLen)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // Add the clear password [null terminated string]
- copy(data[4:], mc.cfg.passwd)
- data[4+pktLen-1] = 0x00
-
- return mc.writePacket(data)
-}
-
-/******************************************************************************
-* Command Packets *
-******************************************************************************/
-
-func (mc *mysqlConn) writeCommandPacket(command byte) error {
- // Reset Packet Sequence
- mc.sequence = 0
-
- data := mc.buf.takeSmallBuffer(4 + 1)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // Add command byte
- data[4] = command
-
- // Send CMD packet
- return mc.writePacket(data)
-}
-
-func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
- // Reset Packet Sequence
- mc.sequence = 0
-
- pktLen := 1 + len(arg)
- data := mc.buf.takeBuffer(pktLen + 4)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // Add command byte
- data[4] = command
-
- // Add arg
- copy(data[5:], arg)
-
- // Send CMD packet
- return mc.writePacket(data)
-}
-
-func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
- // Reset Packet Sequence
- mc.sequence = 0
-
- data := mc.buf.takeSmallBuffer(4 + 1 + 4)
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // Add command byte
- data[4] = command
-
- // Add arg [32 bit]
- data[5] = byte(arg)
- data[6] = byte(arg >> 8)
- data[7] = byte(arg >> 16)
- data[8] = byte(arg >> 24)
-
- // Send CMD packet
- return mc.writePacket(data)
-}
-
-/******************************************************************************
-* Result Packets *
-******************************************************************************/
-
-// Returns error if Packet is not an 'Result OK'-Packet
-func (mc *mysqlConn) readResultOK() error {
- data, err := mc.readPacket()
- if err == nil {
- // packet indicator
- switch data[0] {
-
- case iOK:
- return mc.handleOkPacket(data)
-
- case iEOF:
- if len(data) > 1 {
- plugin := string(data[1:bytes.IndexByte(data, 0x00)])
- if plugin == "mysql_old_password" {
- // using old_passwords
- return ErrOldPassword
- } else if plugin == "mysql_clear_password" {
- // using clear text password
- return ErrCleartextPassword
- } else {
- return ErrUnknownPlugin
- }
- } else {
- return ErrOldPassword
- }
-
- default: // Error otherwise
- return mc.handleErrorPacket(data)
- }
- }
- return err
-}
-
-// Result Set Header Packet
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::Resultset
-func (mc *mysqlConn) readResultSetHeaderPacket() (int, error) {
- data, err := mc.readPacket()
- if err == nil {
- switch data[0] {
-
- case iOK:
- return 0, mc.handleOkPacket(data)
-
- case iERR:
- return 0, mc.handleErrorPacket(data)
-
- case iLocalInFile:
- return 0, mc.handleInFileRequest(string(data[1:]))
- }
-
- // column count
- num, _, n := readLengthEncodedInteger(data)
- if n-len(data) == 0 {
- return int(num), nil
- }
-
- return 0, ErrMalformPkt
- }
- return 0, err
-}
-
-// Error Packet
-// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-ERR_Packet
-func (mc *mysqlConn) handleErrorPacket(data []byte) error {
- if data[0] != iERR {
- return ErrMalformPkt
- }
-
- // 0xff [1 byte]
-
- // Error Number [16 bit uint]
- errno := binary.LittleEndian.Uint16(data[1:3])
-
- pos := 3
-
- // SQL State [optional: # + 5bytes string]
- if data[3] == 0x23 {
- //sqlstate := string(data[4 : 4+5])
- pos = 9
- }
-
- // Error Message [string]
- return &MySQLError{
- Number: errno,
- Message: string(data[pos:]),
- }
-}
-
-// Ok Packet
-// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
-func (mc *mysqlConn) handleOkPacket(data []byte) error {
- var n, m int
-
- // 0x00 [1 byte]
-
- // Affected rows [Length Coded Binary]
- mc.affectedRows, _, n = readLengthEncodedInteger(data[1:])
-
- // Insert id [Length Coded Binary]
- mc.insertId, _, m = readLengthEncodedInteger(data[1+n:])
-
- // server_status [2 bytes]
- mc.status = statusFlag(data[1+n+m]) | statusFlag(data[1+n+m+1])<<8
-
- // warning count [2 bytes]
- if !mc.strict {
- return nil
- } else {
- pos := 1 + n + m + 2
- if binary.LittleEndian.Uint16(data[pos:pos+2]) > 0 {
- return mc.getWarnings()
- }
- return nil
- }
-}
-
-// Read Packets as Field Packets until EOF-Packet or an Error appears
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41
-func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
- columns := make([]mysqlField, count)
-
- for i := 0; ; i++ {
- data, err := mc.readPacket()
- if err != nil {
- return nil, err
- }
-
- // EOF Packet
- if data[0] == iEOF && (len(data) == 5 || len(data) == 1) {
- if i == count {
- return columns, nil
- }
- return nil, fmt.Errorf("ColumnsCount mismatch n:%d len:%d", count, len(columns))
- }
-
- // Catalog
- pos, err := skipLengthEncodedString(data)
- if err != nil {
- return nil, err
- }
-
- // Database [len coded string]
- n, err := skipLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
- pos += n
-
- // Table [len coded string]
- if mc.cfg.columnsWithAlias {
- tableName, _, n, err := readLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
- pos += n
- columns[i].tableName = string(tableName)
- } else {
- n, err = skipLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
- pos += n
- }
-
- // Original table [len coded string]
- n, err = skipLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
- pos += n
-
- // Name [len coded string]
- name, _, n, err := readLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
- columns[i].name = string(name)
- pos += n
-
- // Original name [len coded string]
- n, err = skipLengthEncodedString(data[pos:])
- if err != nil {
- return nil, err
- }
-
- // Filler [uint8]
- // Charset [charset, collation uint8]
- // Length [uint32]
- pos += n + 1 + 2 + 4
-
- // Field type [uint8]
- columns[i].fieldType = data[pos]
- pos++
-
- // Flags [uint16]
- columns[i].flags = fieldFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
- pos += 2
-
- // Decimals [uint8]
- columns[i].decimals = data[pos]
- //pos++
-
- // Default value [len coded binary]
- //if pos < len(data) {
- // defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
- //}
- }
-}
-
-// Read Packets as Field Packets until EOF-Packet or an Error appears
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::ResultsetRow
-func (rows *textRows) readRow(dest []driver.Value) error {
- mc := rows.mc
-
- data, err := mc.readPacket()
- if err != nil {
- return err
- }
-
- // EOF Packet
- if data[0] == iEOF && len(data) == 5 {
- rows.mc = nil
- return io.EOF
- }
- if data[0] == iERR {
- rows.mc = nil
- return mc.handleErrorPacket(data)
- }
-
- // RowSet Packet
- var n int
- var isNull bool
- pos := 0
-
- for i := range dest {
- // Read bytes and convert to string
- dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
- pos += n
- if err == nil {
- if !isNull {
- if !mc.parseTime {
- continue
- } else {
- switch rows.columns[i].fieldType {
- case fieldTypeTimestamp, fieldTypeDateTime,
- fieldTypeDate, fieldTypeNewDate:
- dest[i], err = parseDateTime(
- string(dest[i].([]byte)),
- mc.cfg.loc,
- )
- if err == nil {
- continue
- }
- default:
- continue
- }
- }
-
- } else {
- dest[i] = nil
- continue
- }
- }
- return err // err != nil
- }
-
- return nil
-}
-
-// Reads Packets until EOF-Packet or an Error appears. Returns count of Packets read
-func (mc *mysqlConn) readUntilEOF() error {
- for {
- data, err := mc.readPacket()
-
- // No Err and no EOF Packet
- if err == nil && data[0] != iEOF {
- continue
- }
- return err // Err or EOF
- }
-}
-
-/******************************************************************************
-* Prepared Statements *
-******************************************************************************/
-
-// Prepare Result Packets
-// http://dev.mysql.com/doc/internals/en/com-stmt-prepare-response.html
-func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) {
- data, err := stmt.mc.readPacket()
- if err == nil {
- // packet indicator [1 byte]
- if data[0] != iOK {
- return 0, stmt.mc.handleErrorPacket(data)
- }
-
- // statement id [4 bytes]
- stmt.id = binary.LittleEndian.Uint32(data[1:5])
-
- // Column count [16 bit uint]
- columnCount := binary.LittleEndian.Uint16(data[5:7])
-
- // Param count [16 bit uint]
- stmt.paramCount = int(binary.LittleEndian.Uint16(data[7:9]))
-
- // Reserved [8 bit]
-
- // Warning count [16 bit uint]
- if !stmt.mc.strict {
- return columnCount, nil
- } else {
- // Check for warnings count > 0, only available in MySQL > 4.1
- if len(data) >= 12 && binary.LittleEndian.Uint16(data[10:12]) > 0 {
- return columnCount, stmt.mc.getWarnings()
- }
- return columnCount, nil
- }
- }
- return 0, err
-}
-
-// http://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html
-func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) error {
- maxLen := stmt.mc.maxPacketAllowed - 1
- pktLen := maxLen
-
- // After the header (bytes 0-3) follows before the data:
- // 1 byte command
- // 4 bytes stmtID
- // 2 bytes paramID
- const dataOffset = 1 + 4 + 2
-
- // Can not use the write buffer since
- // a) the buffer is too small
- // b) it is in use
- data := make([]byte, 4+1+4+2+len(arg))
-
- copy(data[4+dataOffset:], arg)
-
- for argLen := len(arg); argLen > 0; argLen -= pktLen - dataOffset {
- if dataOffset+argLen < maxLen {
- pktLen = dataOffset + argLen
- }
-
- stmt.mc.sequence = 0
- // Add command byte [1 byte]
- data[4] = comStmtSendLongData
-
- // Add stmtID [32 bit]
- data[5] = byte(stmt.id)
- data[6] = byte(stmt.id >> 8)
- data[7] = byte(stmt.id >> 16)
- data[8] = byte(stmt.id >> 24)
-
- // Add paramID [16 bit]
- data[9] = byte(paramID)
- data[10] = byte(paramID >> 8)
-
- // Send CMD packet
- err := stmt.mc.writePacket(data[:4+pktLen])
- if err == nil {
- data = data[pktLen-dataOffset:]
- continue
- }
- return err
-
- }
-
- // Reset Packet Sequence
- stmt.mc.sequence = 0
- return nil
-}
-
-// Execute Prepared Statement
-// http://dev.mysql.com/doc/internals/en/com-stmt-execute.html
-func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
- if len(args) != stmt.paramCount {
- return fmt.Errorf(
- "Arguments count mismatch (Got: %d Has: %d)",
- len(args),
- stmt.paramCount,
- )
- }
-
- const minPktLen = 4 + 1 + 4 + 1 + 4
- mc := stmt.mc
-
- // Reset packet-sequence
- mc.sequence = 0
-
- var data []byte
-
- if len(args) == 0 {
- data = mc.buf.takeBuffer(minPktLen)
- } else {
- data = mc.buf.takeCompleteBuffer()
- }
- if data == nil {
- // can not take the buffer. Something must be wrong with the connection
- errLog.Print(ErrBusyBuffer)
- return driver.ErrBadConn
- }
-
- // command [1 byte]
- data[4] = comStmtExecute
-
- // statement_id [4 bytes]
- data[5] = byte(stmt.id)
- data[6] = byte(stmt.id >> 8)
- data[7] = byte(stmt.id >> 16)
- data[8] = byte(stmt.id >> 24)
-
- // flags (0: CURSOR_TYPE_NO_CURSOR) [1 byte]
- data[9] = 0x00
-
- // iteration_count (uint32(1)) [4 bytes]
- data[10] = 0x01
- data[11] = 0x00
- data[12] = 0x00
- data[13] = 0x00
-
- if len(args) > 0 {
- pos := minPktLen
-
- var nullMask []byte
- if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= len(data) {
- // buffer has to be extended but we don't know by how much so
- // we depend on append after all data with known sizes fit.
- // We stop at that because we deal with a lot of columns here
- // which makes the required allocation size hard to guess.
- tmp := make([]byte, pos+maskLen+typesLen)
- copy(tmp[:pos], data[:pos])
- data = tmp
- nullMask = data[pos : pos+maskLen]
- pos += maskLen
- } else {
- nullMask = data[pos : pos+maskLen]
- for i := 0; i < maskLen; i++ {
- nullMask[i] = 0
- }
- pos += maskLen
- }
-
- // newParameterBoundFlag 1 [1 byte]
- data[pos] = 0x01
- pos++
-
- // type of each parameter [len(args)*2 bytes]
- paramTypes := data[pos:]
- pos += len(args) * 2
-
- // value of each parameter [n bytes]
- paramValues := data[pos:pos]
- valuesCap := cap(paramValues)
-
- for i, arg := range args {
- // build NULL-bitmap
- if arg == nil {
- nullMask[i/8] |= 1 << (uint(i) & 7)
- paramTypes[i+i] = fieldTypeNULL
- paramTypes[i+i+1] = 0x00
- continue
- }
-
- // cache types and values
- switch v := arg.(type) {
- case int64:
- paramTypes[i+i] = fieldTypeLongLong
- paramTypes[i+i+1] = 0x00
-
- if cap(paramValues)-len(paramValues)-8 >= 0 {
- paramValues = paramValues[:len(paramValues)+8]
- binary.LittleEndian.PutUint64(
- paramValues[len(paramValues)-8:],
- uint64(v),
- )
- } else {
- paramValues = append(paramValues,
- uint64ToBytes(uint64(v))...,
- )
- }
-
- case float64:
- paramTypes[i+i] = fieldTypeDouble
- paramTypes[i+i+1] = 0x00
-
- if cap(paramValues)-len(paramValues)-8 >= 0 {
- paramValues = paramValues[:len(paramValues)+8]
- binary.LittleEndian.PutUint64(
- paramValues[len(paramValues)-8:],
- math.Float64bits(v),
- )
- } else {
- paramValues = append(paramValues,
- uint64ToBytes(math.Float64bits(v))...,
- )
- }
-
- case bool:
- paramTypes[i+i] = fieldTypeTiny
- paramTypes[i+i+1] = 0x00
-
- if v {
- paramValues = append(paramValues, 0x01)
- } else {
- paramValues = append(paramValues, 0x00)
- }
-
- case []byte:
- // Common case (non-nil value) first
- if v != nil {
- paramTypes[i+i] = fieldTypeString
- paramTypes[i+i+1] = 0x00
-
- if len(v) < mc.maxPacketAllowed-pos-len(paramValues)-(len(args)-(i+1))*64 {
- paramValues = appendLengthEncodedInteger(paramValues,
- uint64(len(v)),
- )
- paramValues = append(paramValues, v...)
- } else {
- if err := stmt.writeCommandLongData(i, v); err != nil {
- return err
- }
- }
- continue
- }
-
- // Handle []byte(nil) as a NULL value
- nullMask[i/8] |= 1 << (uint(i) & 7)
- paramTypes[i+i] = fieldTypeNULL
- paramTypes[i+i+1] = 0x00
-
- case string:
- paramTypes[i+i] = fieldTypeString
- paramTypes[i+i+1] = 0x00
-
- if len(v) < mc.maxPacketAllowed-pos-len(paramValues)-(len(args)-(i+1))*64 {
- paramValues = appendLengthEncodedInteger(paramValues,
- uint64(len(v)),
- )
- paramValues = append(paramValues, v...)
- } else {
- if err := stmt.writeCommandLongData(i, []byte(v)); err != nil {
- return err
- }
- }
-
- case time.Time:
- paramTypes[i+i] = fieldTypeString
- paramTypes[i+i+1] = 0x00
-
- var val []byte
- if v.IsZero() {
- val = []byte("0000-00-00")
- } else {
- val = []byte(v.In(mc.cfg.loc).Format(timeFormat))
- }
-
- paramValues = appendLengthEncodedInteger(paramValues,
- uint64(len(val)),
- )
- paramValues = append(paramValues, val...)
-
- default:
- return fmt.Errorf("Can't convert type: %T", arg)
- }
- }
-
- // Check if param values exceeded the available buffer
- // In that case we must build the data packet with the new values buffer
- if valuesCap != cap(paramValues) {
- data = append(data[:pos], paramValues...)
- mc.buf.buf = data
- }
-
- pos += len(paramValues)
- data = data[:pos]
- }
-
- return mc.writePacket(data)
-}
-
-// http://dev.mysql.com/doc/internals/en/binary-protocol-resultset-row.html
-func (rows *binaryRows) readRow(dest []driver.Value) error {
- data, err := rows.mc.readPacket()
- if err != nil {
- return err
- }
-
- // packet indicator [1 byte]
- if data[0] != iOK {
- rows.mc = nil
- // EOF Packet
- if data[0] == iEOF && len(data) == 5 {
- return io.EOF
- }
-
- // Error otherwise
- return rows.mc.handleErrorPacket(data)
- }
-
- // NULL-bitmap, [(column-count + 7 + 2) / 8 bytes]
- pos := 1 + (len(dest)+7+2)>>3
- nullMask := data[1:pos]
-
- for i := range dest {
- // Field is NULL
- // (byte >> bit-pos) % 2 == 1
- if ((nullMask[(i+2)>>3] >> uint((i+2)&7)) & 1) == 1 {
- dest[i] = nil
- continue
- }
-
- // Convert to byte-coded string
- switch rows.columns[i].fieldType {
- case fieldTypeNULL:
- dest[i] = nil
- continue
-
- // Numeric Types
- case fieldTypeTiny:
- if rows.columns[i].flags&flagUnsigned != 0 {
- dest[i] = int64(data[pos])
- } else {
- dest[i] = int64(int8(data[pos]))
- }
- pos++
- continue
-
- case fieldTypeShort, fieldTypeYear:
- if rows.columns[i].flags&flagUnsigned != 0 {
- dest[i] = int64(binary.LittleEndian.Uint16(data[pos : pos+2]))
- } else {
- dest[i] = int64(int16(binary.LittleEndian.Uint16(data[pos : pos+2])))
- }
- pos += 2
- continue
-
- case fieldTypeInt24, fieldTypeLong:
- if rows.columns[i].flags&flagUnsigned != 0 {
- dest[i] = int64(binary.LittleEndian.Uint32(data[pos : pos+4]))
- } else {
- dest[i] = int64(int32(binary.LittleEndian.Uint32(data[pos : pos+4])))
- }
- pos += 4
- continue
-
- case fieldTypeLongLong:
- if rows.columns[i].flags&flagUnsigned != 0 {
- val := binary.LittleEndian.Uint64(data[pos : pos+8])
- if val > math.MaxInt64 {
- dest[i] = uint64ToString(val)
- } else {
- dest[i] = int64(val)
- }
- } else {
- dest[i] = int64(binary.LittleEndian.Uint64(data[pos : pos+8]))
- }
- pos += 8
- continue
-
- case fieldTypeFloat:
- dest[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4])))
- pos += 4
- continue
-
- case fieldTypeDouble:
- dest[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[pos : pos+8]))
- pos += 8
- continue
-
- // Length coded Binary Strings
- case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
- fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
- fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
- fieldTypeVarString, fieldTypeString, fieldTypeGeometry:
- var isNull bool
- var n int
- dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
- pos += n
- if err == nil {
- if !isNull {
- continue
- } else {
- dest[i] = nil
- continue
- }
- }
- return err
-
- case
- fieldTypeDate, fieldTypeNewDate, // Date YYYY-MM-DD
- fieldTypeTime, // Time [-][H]HH:MM:SS[.fractal]
- fieldTypeTimestamp, fieldTypeDateTime: // Timestamp YYYY-MM-DD HH:MM:SS[.fractal]
-
- num, isNull, n := readLengthEncodedInteger(data[pos:])
- pos += n
-
- switch {
- case isNull:
- dest[i] = nil
- continue
- case rows.columns[i].fieldType == fieldTypeTime:
- // database/sql does not support an equivalent to TIME, return a string
- var dstlen uint8
- switch decimals := rows.columns[i].decimals; decimals {
- case 0x00, 0x1f:
- dstlen = 8
- case 1, 2, 3, 4, 5, 6:
- dstlen = 8 + 1 + decimals
- default:
- return fmt.Errorf(
- "MySQL protocol error, illegal decimals value %d",
- rows.columns[i].decimals,
- )
- }
- dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, true)
- case rows.mc.parseTime:
- dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.loc)
- default:
- var dstlen uint8
- if rows.columns[i].fieldType == fieldTypeDate {
- dstlen = 10
- } else {
- switch decimals := rows.columns[i].decimals; decimals {
- case 0x00, 0x1f:
- dstlen = 19
- case 1, 2, 3, 4, 5, 6:
- dstlen = 19 + 1 + decimals
- default:
- return fmt.Errorf(
- "MySQL protocol error, illegal decimals value %d",
- rows.columns[i].decimals,
- )
- }
- }
- dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, false)
- }
-
- if err == nil {
- pos += int(num)
- continue
- } else {
- return err
- }
-
- // Please report if this happens!
- default:
- return fmt.Errorf("Unknown FieldType %d", rows.columns[i].fieldType)
- }
- }
-
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go
deleted file mode 100644
index c6438d034..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-type mysqlResult struct {
- affectedRows int64
- insertId int64
-}
-
-func (res *mysqlResult) LastInsertId() (int64, error) {
- return res.insertId, nil
-}
-
-func (res *mysqlResult) RowsAffected() (int64, error) {
- return res.affectedRows, nil
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/rows.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/rows.go
deleted file mode 100644
index ba606e146..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/rows.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "database/sql/driver"
- "io"
-)
-
-type mysqlField struct {
- tableName string
- name string
- flags fieldFlag
- fieldType byte
- decimals byte
-}
-
-type mysqlRows struct {
- mc *mysqlConn
- columns []mysqlField
-}
-
-type binaryRows struct {
- mysqlRows
-}
-
-type textRows struct {
- mysqlRows
-}
-
-type emptyRows struct{}
-
-func (rows *mysqlRows) Columns() []string {
- columns := make([]string, len(rows.columns))
- if rows.mc.cfg.columnsWithAlias {
- for i := range columns {
- if tableName := rows.columns[i].tableName; len(tableName) > 0 {
- columns[i] = tableName + "." + rows.columns[i].name
- } else {
- columns[i] = rows.columns[i].name
- }
- }
- } else {
- for i := range columns {
- columns[i] = rows.columns[i].name
- }
- }
- return columns
-}
-
-func (rows *mysqlRows) Close() error {
- mc := rows.mc
- if mc == nil {
- return nil
- }
- if mc.netConn == nil {
- return ErrInvalidConn
- }
-
- // Remove unread packets from stream
- err := mc.readUntilEOF()
- rows.mc = nil
- return err
-}
-
-func (rows *binaryRows) Next(dest []driver.Value) error {
- if mc := rows.mc; mc != nil {
- if mc.netConn == nil {
- return ErrInvalidConn
- }
-
- // Fetch next row from stream
- return rows.readRow(dest)
- }
- return io.EOF
-}
-
-func (rows *textRows) Next(dest []driver.Value) error {
- if mc := rows.mc; mc != nil {
- if mc.netConn == nil {
- return ErrInvalidConn
- }
-
- // Fetch next row from stream
- return rows.readRow(dest)
- }
- return io.EOF
-}
-
-func (rows emptyRows) Columns() []string {
- return nil
-}
-
-func (rows emptyRows) Close() error {
- return nil
-}
-
-func (rows emptyRows) Next(dest []driver.Value) error {
- return io.EOF
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/statement.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/statement.go
deleted file mode 100644
index 6e869b340..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/statement.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "database/sql/driver"
- "fmt"
- "reflect"
- "strconv"
-)
-
-type mysqlStmt struct {
- mc *mysqlConn
- id uint32
- paramCount int
- columns []mysqlField // cached from the first query
-}
-
-func (stmt *mysqlStmt) Close() error {
- if stmt.mc == nil || stmt.mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return driver.ErrBadConn
- }
-
- err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id)
- stmt.mc = nil
- return err
-}
-
-func (stmt *mysqlStmt) NumInput() int {
- return stmt.paramCount
-}
-
-func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
- return converter{}
-}
-
-func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
- if stmt.mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- // Send command
- err := stmt.writeExecutePacket(args)
- if err != nil {
- return nil, err
- }
-
- mc := stmt.mc
-
- mc.affectedRows = 0
- mc.insertId = 0
-
- // Read Result
- resLen, err := mc.readResultSetHeaderPacket()
- if err == nil {
- if resLen > 0 {
- // Columns
- err = mc.readUntilEOF()
- if err != nil {
- return nil, err
- }
-
- // Rows
- err = mc.readUntilEOF()
- }
- if err == nil {
- return &mysqlResult{
- affectedRows: int64(mc.affectedRows),
- insertId: int64(mc.insertId),
- }, nil
- }
- }
-
- return nil, err
-}
-
-func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
- if stmt.mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
- return nil, driver.ErrBadConn
- }
- // Send command
- err := stmt.writeExecutePacket(args)
- if err != nil {
- return nil, err
- }
-
- mc := stmt.mc
-
- // Read Result
- resLen, err := mc.readResultSetHeaderPacket()
- if err != nil {
- return nil, err
- }
-
- rows := new(binaryRows)
- rows.mc = mc
-
- if resLen > 0 {
- // Columns
- // If not cached, read them and cache them
- if stmt.columns == nil {
- rows.columns, err = mc.readColumns(resLen)
- stmt.columns = rows.columns
- } else {
- rows.columns = stmt.columns
- err = mc.readUntilEOF()
- }
- }
-
- return rows, err
-}
-
-type converter struct{}
-
-func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
- if driver.IsValue(v) {
- return v, nil
- }
-
- rv := reflect.ValueOf(v)
- switch rv.Kind() {
- case reflect.Ptr:
- // indirect pointers
- if rv.IsNil() {
- return nil, nil
- }
- return c.ConvertValue(rv.Elem().Interface())
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return rv.Int(), nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
- return int64(rv.Uint()), nil
- case reflect.Uint64:
- u64 := rv.Uint()
- if u64 >= 1<<63 {
- return strconv.FormatUint(u64, 10), nil
- }
- return int64(u64), nil
- case reflect.Float32, reflect.Float64:
- return rv.Float(), nil
- }
- return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go
deleted file mode 100644
index 33c749b35..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-type mysqlTx struct {
- mc *mysqlConn
-}
-
-func (tx *mysqlTx) Commit() (err error) {
- if tx.mc == nil || tx.mc.netConn == nil {
- return ErrInvalidConn
- }
- err = tx.mc.exec("COMMIT")
- tx.mc = nil
- return
-}
-
-func (tx *mysqlTx) Rollback() (err error) {
- if tx.mc == nil || tx.mc.netConn == nil {
- return ErrInvalidConn
- }
- err = tx.mc.exec("ROLLBACK")
- tx.mc = nil
- return
-}
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/utils.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/utils.go
deleted file mode 100644
index 6a26ad129..000000000
--- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/utils.go
+++ /dev/null
@@ -1,973 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
- "crypto/sha1"
- "crypto/tls"
- "database/sql/driver"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "net"
- "net/url"
- "strings"
- "time"
-)
-
-var (
- tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs
-
- errInvalidDSNUnescaped = errors.New("Invalid DSN: Did you forget to escape a param value?")
- errInvalidDSNAddr = errors.New("Invalid DSN: Network Address not terminated (missing closing brace)")
- errInvalidDSNNoSlash = errors.New("Invalid DSN: Missing the slash separating the database name")
- errInvalidDSNUnsafeCollation = errors.New("Invalid DSN: interpolateParams can be used with ascii, latin1, utf8 and utf8mb4 charset")
-)
-
-func init() {
- tlsConfigRegister = make(map[string]*tls.Config)
-}
-
-// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.
-// Use the key as a value in the DSN where tls=value.
-//
-// rootCertPool := x509.NewCertPool()
-// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
-// if err != nil {
-// log.Fatal(err)
-// }
-// if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
-// log.Fatal("Failed to append PEM.")
-// }
-// clientCert := make([]tls.Certificate, 0, 1)
-// certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem")
-// if err != nil {
-// log.Fatal(err)
-// }
-// clientCert = append(clientCert, certs)
-// mysql.RegisterTLSConfig("custom", &tls.Config{
-// RootCAs: rootCertPool,
-// Certificates: clientCert,
-// })
-// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
-//
-func RegisterTLSConfig(key string, config *tls.Config) error {
- if _, isBool := readBool(key); isBool || strings.ToLower(key) == "skip-verify" {
- return fmt.Errorf("Key '%s' is reserved", key)
- }
-
- tlsConfigRegister[key] = config
- return nil
-}
-
-// DeregisterTLSConfig removes the tls.Config associated with key.
-func DeregisterTLSConfig(key string) {
- delete(tlsConfigRegister, key)
-}
-
-// parseDSN parses the DSN string to a config
-func parseDSN(dsn string) (cfg *config, err error) {
- // New config with some default values
- cfg = &config{
- loc: time.UTC,
- collation: defaultCollation,
- }
-
- // [user[:password]@][net[(addr)]]/dbname[?param1=value1&paramN=valueN]
- // Find the last '/' (since the password or the net addr might contain a '/')
- foundSlash := false
- for i := len(dsn) - 1; i >= 0; i-- {
- if dsn[i] == '/' {
- foundSlash = true
- var j, k int
-
- // left part is empty if i <= 0
- if i > 0 {
- // [username[:password]@][protocol[(address)]]
- // Find the last '@' in dsn[:i]
- for j = i; j >= 0; j-- {
- if dsn[j] == '@' {
- // username[:password]
- // Find the first ':' in dsn[:j]
- for k = 0; k < j; k++ {
- if dsn[k] == ':' {
- cfg.passwd = dsn[k+1 : j]
- break
- }
- }
- cfg.user = dsn[:k]
-
- break
- }
- }
-
- // [protocol[(address)]]
- // Find the first '(' in dsn[j+1:i]
- for k = j + 1; k < i; k++ {
- if dsn[k] == '(' {
- // dsn[i-1] must be == ')' if an address is specified
- if dsn[i-1] != ')' {
- if strings.ContainsRune(dsn[k+1:i], ')') {
- return nil, errInvalidDSNUnescaped
- }
- return nil, errInvalidDSNAddr
- }
- cfg.addr = dsn[k+1 : i-1]
- break
- }
- }
- cfg.net = dsn[j+1 : k]
- }
-
- // dbname[?param1=value1&...&paramN=valueN]
- // Find the first '?' in dsn[i+1:]
- for j = i + 1; j < len(dsn); j++ {
- if dsn[j] == '?' {
- if err = parseDSNParams(cfg, dsn[j+1:]); err != nil {
- return
- }
- break
- }
- }
- cfg.dbname = dsn[i+1 : j]
-
- break
- }
- }
-
- if !foundSlash && len(dsn) > 0 {
- return nil, errInvalidDSNNoSlash
- }
-
- if cfg.interpolateParams && unsafeCollations[cfg.collation] {
- return nil, errInvalidDSNUnsafeCollation
- }
-
- // Set default network if empty
- if cfg.net == "" {
- cfg.net = "tcp"
- }
-
- // Set default address if empty
- if cfg.addr == "" {
- switch cfg.net {
- case "tcp":
- cfg.addr = "127.0.0.1:3306"
- case "unix":
- cfg.addr = "/tmp/mysql.sock"
- default:
- return nil, errors.New("Default addr for network '" + cfg.net + "' unknown")
- }
-
- }
-
- return
-}
-
-// parseDSNParams parses the DSN "query string"
-// Values must be url.QueryEscape'ed
-func parseDSNParams(cfg *config, params string) (err error) {
- for _, v := range strings.Split(params, "&") {
- param := strings.SplitN(v, "=", 2)
- if len(param) != 2 {
- continue
- }
-
- // cfg params
- switch value := param[1]; param[0] {
-
- // Enable client side placeholder substitution
- case "interpolateParams":
- var isBool bool
- cfg.interpolateParams, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Disable INFILE whitelist / enable all files
- case "allowAllFiles":
- var isBool bool
- cfg.allowAllFiles, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Use cleartext authentication mode (MySQL 5.5.10+)
- case "allowCleartextPasswords":
- var isBool bool
- cfg.allowCleartextPasswords, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Use old authentication mode (pre MySQL 4.1)
- case "allowOldPasswords":
- var isBool bool
- cfg.allowOldPasswords, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Switch "rowsAffected" mode
- case "clientFoundRows":
- var isBool bool
- cfg.clientFoundRows, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Collation
- case "collation":
- collation, ok := collations[value]
- if !ok {
- // Note possibility for false negatives:
- // could be triggered although the collation is valid if the
- // collations map does not contain entries the server supports.
- err = errors.New("unknown collation")
- return
- }
- cfg.collation = collation
- break
-
- case "columnsWithAlias":
- var isBool bool
- cfg.columnsWithAlias, isBool = readBool(value)
- if !isBool {
- return fmt.Errorf("Invalid Bool value: %s", value)
- }
-
- // Time Location
- case "loc":
- if value, err = url.QueryUnescape(value); err != nil {
- return
- }
- cfg.loc, err = time.LoadLocation(value)
- if err != nil {
- return
- }
-
- // Dial Timeout
- case "timeout":
- cfg.timeout, err = time.ParseDuration(value)
- if err != nil {
- return
- }
-
- // TLS-Encryption
- case "tls":
- boolValue, isBool := readBool(value)
- if isBool {
- if boolValue {
- cfg.tls = &tls.Config{}
- }
- } else {
- if strings.ToLower(value) == "skip-verify" {
- cfg.tls = &tls.Config{InsecureSkipVerify: true}
- } else if tlsConfig, ok := tlsConfigRegister[value]; ok {
- if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify {
- host, _, err := net.SplitHostPort(cfg.addr)
- if err == nil {
- tlsConfig.ServerName = host
- }
- }
-
- cfg.tls = tlsConfig
- } else {
- return fmt.Errorf("Invalid value / unknown config name: %s", value)
- }
- }
-
- default:
- // lazy init
- if cfg.params == nil {
- cfg.params = make(map[string]string)
- }
-
- if cfg.params[param[0]], err = url.QueryUnescape(value); err != nil {
- return
- }
- }
- }
-
- return
-}
-
-// Returns the bool value of the input.
-// The 2nd return value indicates if the input was a valid bool value
-func readBool(input string) (value bool, valid bool) {
- switch input {
- case "1", "true", "TRUE", "True":
- return true, true
- case "0", "false", "FALSE", "False":
- return false, true
- }
-
- // Not a valid bool value
- return
-}
-
-/******************************************************************************
-* Authentication *
-******************************************************************************/
-
-// Encrypt password using 4.1+ method
-func scramblePassword(scramble, password []byte) []byte {
- if len(password) == 0 {
- return nil
- }
-
- // stage1Hash = SHA1(password)
- crypt := sha1.New()
- crypt.Write(password)
- stage1 := crypt.Sum(nil)
-
- // scrambleHash = SHA1(scramble + SHA1(stage1Hash))
- // inner Hash
- crypt.Reset()
- crypt.Write(stage1)
- hash := crypt.Sum(nil)
-
- // outer Hash
- crypt.Reset()
- crypt.Write(scramble)
- crypt.Write(hash)
- scramble = crypt.Sum(nil)
-
- // token = scrambleHash XOR stage1Hash
- for i := range scramble {
- scramble[i] ^= stage1[i]
- }
- return scramble
-}
-
-// Encrypt password using pre 4.1 (old password) method
-// https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c
-type myRnd struct {
- seed1, seed2 uint32
-}
-
-const myRndMaxVal = 0x3FFFFFFF
-
-// Pseudo random number generator
-func newMyRnd(seed1, seed2 uint32) *myRnd {
- return &myRnd{
- seed1: seed1 % myRndMaxVal,
- seed2: seed2 % myRndMaxVal,
- }
-}
-
-// Tested to be equivalent to MariaDB's floating point variant
-// http://play.golang.org/p/QHvhd4qved
-// http://play.golang.org/p/RG0q4ElWDx
-func (r *myRnd) NextByte() byte {
- r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal
- r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal
-
- return byte(uint64(r.seed1) * 31 / myRndMaxVal)
-}
-
-// Generate binary hash from byte string using insecure pre 4.1 method
-func pwHash(password []byte) (result [2]uint32) {
- var add uint32 = 7
- var tmp uint32
-
- result[0] = 1345345333
- result[1] = 0x12345671
-
- for _, c := range password {
- // skip spaces and tabs in password
- if c == ' ' || c == '\t' {
- continue
- }
-
- tmp = uint32(c)
- result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8)
- result[1] += (result[1] << 8) ^ result[0]
- add += tmp
- }
-
- // Remove sign bit (1<<31)-1)
- result[0] &= 0x7FFFFFFF
- result[1] &= 0x7FFFFFFF
-
- return
-}
-
-// Encrypt password using insecure pre 4.1 method
-func scrambleOldPassword(scramble, password []byte) []byte {
- if len(password) == 0 {
- return nil
- }
-
- scramble = scramble[:8]
-
- hashPw := pwHash(password)
- hashSc := pwHash(scramble)
-
- r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1])
-
- var out [8]byte
- for i := range out {
- out[i] = r.NextByte() + 64
- }
-
- mask := r.NextByte()
- for i := range out {
- out[i] ^= mask
- }
-
- return out[:]
-}
-
-/******************************************************************************
-* Time related utils *
-******************************************************************************/
-
-// NullTime represents a time.Time that may be NULL.
-// NullTime implements the Scanner interface so
-// it can be used as a scan destination:
-//
-// var nt NullTime
-// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt)
-// ...
-// if nt.Valid {
-// // use nt.Time
-// } else {
-// // NULL value
-// }
-//
-// This NullTime implementation is not driver-specific
-type NullTime struct {
- Time time.Time
- Valid bool // Valid is true if Time is not NULL
-}
-
-// Scan implements the Scanner interface.
-// The value type must be time.Time or string / []byte (formatted time-string),
-// otherwise Scan fails.
-func (nt *NullTime) Scan(value interface{}) (err error) {
- if value == nil {
- nt.Time, nt.Valid = time.Time{}, false
- return
- }
-
- switch v := value.(type) {
- case time.Time:
- nt.Time, nt.Valid = v, true
- return
- case []byte:
- nt.Time, err = parseDateTime(string(v), time.UTC)
- nt.Valid = (err == nil)
- return
- case string:
- nt.Time, err = parseDateTime(v, time.UTC)
- nt.Valid = (err == nil)
- return
- }
-
- nt.Valid = false
- return fmt.Errorf("Can't convert %T to time.Time", value)
-}
-
-// Value implements the driver Valuer interface.
-func (nt NullTime) Value() (driver.Value, error) {
- if !nt.Valid {
- return nil, nil
- }
- return nt.Time, nil
-}
-
-func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
- base := "0000-00-00 00:00:00.0000000"
- switch len(str) {
- case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
- if str == base[:len(str)] {
- return
- }
- t, err = time.Parse(timeFormat[:len(str)], str)
- default:
- err = fmt.Errorf("Invalid Time-String: %s", str)
- return
- }
-
- // Adjust location
- if err == nil && loc != time.UTC {
- y, mo, d := t.Date()
- h, mi, s := t.Clock()
- t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
- }
-
- return
-}
-
-func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) {
- switch num {
- case 0:
- return time.Time{}, nil
- case 4:
- return time.Date(
- int(binary.LittleEndian.Uint16(data[:2])), // year
- time.Month(data[2]), // month
- int(data[3]), // day
- 0, 0, 0, 0,
- loc,
- ), nil
- case 7:
- return time.Date(
- int(binary.LittleEndian.Uint16(data[:2])), // year
- time.Month(data[2]), // month
- int(data[3]), // day
- int(data[4]), // hour
- int(data[5]), // minutes
- int(data[6]), // seconds
- 0,
- loc,
- ), nil
- case 11:
- return time.Date(
- int(binary.LittleEndian.Uint16(data[:2])), // year
- time.Month(data[2]), // month
- int(data[3]), // day
- int(data[4]), // hour
- int(data[5]), // minutes
- int(data[6]), // seconds
- int(binary.LittleEndian.Uint32(data[7:11]))*1000, // nanoseconds
- loc,
- ), nil
- }
- return nil, fmt.Errorf("Invalid DATETIME-packet length %d", num)
-}
-
-// zeroDateTime is used in formatBinaryDateTime to avoid an allocation
-// if the DATE or DATETIME has the zero value.
-// It must never be changed.
-// The current behavior depends on database/sql copying the result.
-var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
-
-const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
-const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
-
-func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value, error) {
- // length expects the deterministic length of the zero value,
- // negative time and 100+ hours are automatically added if needed
- if len(src) == 0 {
- if justTime {
- return zeroDateTime[11 : 11+length], nil
- }
- return zeroDateTime[:length], nil
- }
- var dst []byte // return value
- var pt, p1, p2, p3 byte // current digit pair
- var zOffs byte // offset of value in zeroDateTime
- if justTime {
- switch length {
- case
- 8, // time (can be up to 10 when negative and 100+ hours)
- 10, 11, 12, 13, 14, 15: // time with fractional seconds
- default:
- return nil, fmt.Errorf("illegal TIME length %d", length)
- }
- switch len(src) {
- case 8, 12:
- default:
- return nil, fmt.Errorf("Invalid TIME-packet length %d", len(src))
- }
- // +2 to enable negative time and 100+ hours
- dst = make([]byte, 0, length+2)
- if src[0] == 1 {
- dst = append(dst, '-')
- }
- if src[1] != 0 {
- hour := uint16(src[1])*24 + uint16(src[5])
- pt = byte(hour / 100)
- p1 = byte(hour - 100*uint16(pt))
- dst = append(dst, digits01[pt])
- } else {
- p1 = src[5]
- }
- zOffs = 11
- src = src[6:]
- } else {
- switch length {
- case 10, 19, 21, 22, 23, 24, 25, 26:
- default:
- t := "DATE"
- if length > 10 {
- t += "TIME"
- }
- return nil, fmt.Errorf("illegal %s length %d", t, length)
- }
- switch len(src) {
- case 4, 7, 11:
- default:
- t := "DATE"
- if length > 10 {
- t += "TIME"
- }
- return nil, fmt.Errorf("illegal %s-packet length %d", t, len(src))
- }
- dst = make([]byte, 0, length)
- // start with the date
- year := binary.LittleEndian.Uint16(src[:2])
- pt = byte(year / 100)
- p1 = byte(year - 100*uint16(pt))
- p2, p3 = src[2], src[3]
- dst = append(dst,
- digits10[pt], digits01[pt],
- digits10[p1], digits01[p1], '-',
- digits10[p2], digits01[p2], '-',
- digits10[p3], digits01[p3],
- )
- if length == 10 {
- return dst, nil
- }
- if len(src) == 4 {
- return append(dst, zeroDateTime[10:length]...), nil
- }
- dst = append(dst, ' ')
- p1 = src[4] // hour
- src = src[5:]
- }
- // p1 is 2-digit hour, src is after hour
- p2, p3 = src[0], src[1]
- dst = append(dst,
- digits10[p1], digits01[p1], ':',
- digits10[p2], digits01[p2], ':',
- digits10[p3], digits01[p3],
- )
- if length <= byte(len(dst)) {
- return dst, nil
- }
- src = src[2:]
- if len(src) == 0 {
- return append(dst, zeroDateTime[19:zOffs+length]...), nil
- }
- microsecs := binary.LittleEndian.Uint32(src[:4])
- p1 = byte(microsecs / 10000)
- microsecs -= 10000 * uint32(p1)
- p2 = byte(microsecs / 100)
- microsecs -= 100 * uint32(p2)
- p3 = byte(microsecs)
- switch decimals := zOffs + length - 20; decimals {
- default:
- return append(dst, '.',
- digits10[p1], digits01[p1],
- digits10[p2], digits01[p2],
- digits10[p3], digits01[p3],
- ), nil
- case 1:
- return append(dst, '.',
- digits10[p1],
- ), nil
- case 2:
- return append(dst, '.',
- digits10[p1], digits01[p1],
- ), nil
- case 3:
- return append(dst, '.',
- digits10[p1], digits01[p1],
- digits10[p2],
- ), nil
- case 4:
- return append(dst, '.',
- digits10[p1], digits01[p1],
- digits10[p2], digits01[p2],
- ), nil
- case 5:
- return append(dst, '.',
- digits10[p1], digits01[p1],
- digits10[p2], digits01[p2],
- digits10[p3],
- ), nil
- }
-}
-
-/******************************************************************************
-* Convert from and to bytes *
-******************************************************************************/
-
-func uint64ToBytes(n uint64) []byte {
- return []byte{
- byte(n),
- byte(n >> 8),
- byte(n >> 16),
- byte(n >> 24),
- byte(n >> 32),
- byte(n >> 40),
- byte(n >> 48),
- byte(n >> 56),
- }
-}
-
-func uint64ToString(n uint64) []byte {
- var a [20]byte
- i := 20
-
- // U+0030 = 0
- // ...
- // U+0039 = 9
-
- var q uint64
- for n >= 10 {
- i--
- q = n / 10
- a[i] = uint8(n-q*10) + 0x30
- n = q
- }
-
- i--
- a[i] = uint8(n) + 0x30
-
- return a[i:]
-}
-
-// treats string value as unsigned integer representation
-func stringToInt(b []byte) int {
- val := 0
- for i := range b {
- val *= 10
- val += int(b[i] - 0x30)
- }
- return val
-}
-
-// returns the string read as a bytes slice, wheter the value is NULL,
-// the number of bytes read and an error, in case the string is longer than
-// the input slice
-func readLengthEncodedString(b []byte) ([]byte, bool, int, error) {
- // Get length
- num, isNull, n := readLengthEncodedInteger(b)
- if num < 1 {
- return b[n:n], isNull, n, nil
- }
-
- n += int(num)
-
- // Check data length
- if len(b) >= n {
- return b[n-int(num) : n], false, n, nil
- }
- return nil, false, n, io.EOF
-}
-
-// returns the number of bytes skipped and an error, in case the string is
-// longer than the input slice
-func skipLengthEncodedString(b []byte) (int, error) {
- // Get length
- num, _, n := readLengthEncodedInteger(b)
- if num < 1 {
- return n, nil
- }
-
- n += int(num)
-
- // Check data length
- if len(b) >= n {
- return n, nil
- }
- return n, io.EOF
-}
-
-// returns the number read, whether the value is NULL and the number of bytes read
-func readLengthEncodedInteger(b []byte) (uint64, bool, int) {
- // See issue #349
- if len(b) == 0 {
- return 0, true, 1
- }
- switch b[0] {
-
- // 251: NULL
- case 0xfb:
- return 0, true, 1
-
- // 252: value of following 2
- case 0xfc:
- return uint64(b[1]) | uint64(b[2])<<8, false, 3
-
- // 253: value of following 3
- case 0xfd:
- return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16, false, 4
-
- // 254: value of following 8
- case 0xfe:
- return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 |
- uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 |
- uint64(b[7])<<48 | uint64(b[8])<<56,
- false, 9
- }
-
- // 0-250: value of first byte
- return uint64(b[0]), false, 1
-}
-
-// encodes a uint64 value and appends it to the given bytes slice
-func appendLengthEncodedInteger(b []byte, n uint64) []byte {
- switch {
- case n <= 250:
- return append(b, byte(n))
-
- case n <= 0xffff:
- return append(b, 0xfc, byte(n), byte(n>>8))
-
- case n <= 0xffffff:
- return append(b, 0xfd, byte(n), byte(n>>8), byte(n>>16))
- }
- return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24),
- byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56))
-}
-
-// reserveBuffer checks cap(buf) and expand buffer to len(buf) + appendSize.
-// If cap(buf) is not enough, reallocate new buffer.
-func reserveBuffer(buf []byte, appendSize int) []byte {
- newSize := len(buf) + appendSize
- if cap(buf) < newSize {
- // Grow buffer exponentially
- newBuf := make([]byte, len(buf)*2+appendSize)
- copy(newBuf, buf)
- buf = newBuf
- }
- return buf[:newSize]
-}
-
-// escapeBytesBackslash escapes []byte with backslashes (\)
-// This escapes the contents of a string (provided as []byte) by adding backslashes before special
-// characters, and turning others into specific escape sequences, such as
-// turning newlines into \n and null bytes into \0.
-// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L823-L932
-func escapeBytesBackslash(buf, v []byte) []byte {
- pos := len(buf)
- buf = reserveBuffer(buf, len(v)*2)
-
- for _, c := range v {
- switch c {
- case '\x00':
- buf[pos] = '\\'
- buf[pos+1] = '0'
- pos += 2
- case '\n':
- buf[pos] = '\\'
- buf[pos+1] = 'n'
- pos += 2
- case '\r':
- buf[pos] = '\\'
- buf[pos+1] = 'r'
- pos += 2
- case '\x1a':
- buf[pos] = '\\'
- buf[pos+1] = 'Z'
- pos += 2
- case '\'':
- buf[pos] = '\\'
- buf[pos+1] = '\''
- pos += 2
- case '"':
- buf[pos] = '\\'
- buf[pos+1] = '"'
- pos += 2
- case '\\':
- buf[pos] = '\\'
- buf[pos+1] = '\\'
- pos += 2
- default:
- buf[pos] = c
- pos += 1
- }
- }
-
- return buf[:pos]
-}
-
-// escapeStringBackslash is similar to escapeBytesBackslash but for string.
-func escapeStringBackslash(buf []byte, v string) []byte {
- pos := len(buf)
- buf = reserveBuffer(buf, len(v)*2)
-
- for i := 0; i < len(v); i++ {
- c := v[i]
- switch c {
- case '\x00':
- buf[pos] = '\\'
- buf[pos+1] = '0'
- pos += 2
- case '\n':
- buf[pos] = '\\'
- buf[pos+1] = 'n'
- pos += 2
- case '\r':
- buf[pos] = '\\'
- buf[pos+1] = 'r'
- pos += 2
- case '\x1a':
- buf[pos] = '\\'
- buf[pos+1] = 'Z'
- pos += 2
- case '\'':
- buf[pos] = '\\'
- buf[pos+1] = '\''
- pos += 2
- case '"':
- buf[pos] = '\\'
- buf[pos+1] = '"'
- pos += 2
- case '\\':
- buf[pos] = '\\'
- buf[pos+1] = '\\'
- pos += 2
- default:
- buf[pos] = c
- pos += 1
- }
- }
-
- return buf[:pos]
-}
-
-// escapeBytesQuotes escapes apostrophes in []byte by doubling them up.
-// This escapes the contents of a string by doubling up any apostrophes that
-// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
-// effect on the server.
-// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L963-L1038
-func escapeBytesQuotes(buf, v []byte) []byte {
- pos := len(buf)
- buf = reserveBuffer(buf, len(v)*2)
-
- for _, c := range v {
- if c == '\'' {
- buf[pos] = '\''
- buf[pos+1] = '\''
- pos += 2
- } else {
- buf[pos] = c
- pos++
- }
- }
-
- return buf[:pos]
-}
-
-// escapeStringQuotes is similar to escapeBytesQuotes but for string.
-func escapeStringQuotes(buf []byte, v string) []byte {
- pos := len(buf)
- buf = reserveBuffer(buf, len(v)*2)
-
- for i := 0; i < len(v); i++ {
- c := v[i]
- if c == '\'' {
- buf[pos] = '\''
- buf[pos+1] = '\''
- pos += 2
- } else {
- buf[pos] = c
- pos++
- }
- }
-
- return buf[:pos]
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE b/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE
deleted file mode 100644
index 53320c352..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE
+++ /dev/null
@@ -1,185 +0,0 @@
-This software is licensed under the LGPLv3, included below.
-
-As a special exception to the GNU Lesser General Public License version 3
-("LGPL3"), the copyright holders of this Library give you permission to
-convey to a third party a Combined Work that links statically or dynamically
-to this Library without providing any Minimal Corresponding Source or
-Minimal Application Code as set out in 4d or providing the installation
-information set out in section 4e, provided that you comply with the other
-provisions of LGPL3 and provided that you meet, for the Application the
-terms and conditions of the license(s) which apply to the Application.
-
-Except as stated in this special exception, the provisions of LGPL3 will
-continue to comply in full to this Library. If you modify this Library, you
-may apply this exception to your version of this Library, but you are not
-obliged to do so. If you do not wish to do so, delete this exception
-statement from your version. This exception does not (and cannot) modify any
-license terms which apply to the Application, with which you must still
-comply.
-
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt.go
deleted file mode 100644
index c0654f5d8..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package aws
-
-import (
- "time"
-)
-
-// AttemptStrategy represents a strategy for waiting for an action
-// to complete successfully. This is an internal type used by the
-// implementation of other goamz packages.
-type AttemptStrategy struct {
- Total time.Duration // total duration of attempt.
- Delay time.Duration // interval between each try in the burst.
- Min int // minimum number of retries; overrides Total
-}
-
-type Attempt struct {
- strategy AttemptStrategy
- last time.Time
- end time.Time
- force bool
- count int
-}
-
-// Start begins a new sequence of attempts for the given strategy.
-func (s AttemptStrategy) Start() *Attempt {
- now := time.Now()
- return &Attempt{
- strategy: s,
- last: now,
- end: now.Add(s.Total),
- force: true,
- }
-}
-
-// Next waits until it is time to perform the next attempt or returns
-// false if it is time to stop trying.
-func (a *Attempt) Next() bool {
- now := time.Now()
- sleep := a.nextSleep(now)
- if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count {
- return false
- }
- a.force = false
- if sleep > 0 && a.count > 0 {
- time.Sleep(sleep)
- now = time.Now()
- }
- a.count++
- a.last = now
- return true
-}
-
-func (a *Attempt) nextSleep(now time.Time) time.Duration {
- sleep := a.strategy.Delay - now.Sub(a.last)
- if sleep < 0 {
- return 0
- }
- return sleep
-}
-
-// HasNext returns whether another attempt will be made if the current
-// one fails. If it returns true, the following call to Next is
-// guaranteed to return true.
-func (a *Attempt) HasNext() bool {
- if a.force || a.strategy.Min > a.count {
- return true
- }
- now := time.Now()
- if now.Add(a.nextSleep(now)).Before(a.end) {
- a.force = true
- return true
- }
- return false
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws.go
deleted file mode 100644
index 77bf563d6..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws.go
+++ /dev/null
@@ -1,432 +0,0 @@
-//
-// goamz - Go packages to interact with the Amazon Web Services.
-//
-// https://wiki.ubuntu.com/goamz
-//
-// Copyright (c) 2011 Canonical Ltd.
-//
-// Written by Gustavo Niemeyer <gustavo.niemeyer@canonical.com>
-//
-package aws
-
-import (
- "encoding/json"
- "encoding/xml"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/url"
- "os"
- "time"
-
- "github.com/vaughan0/go-ini"
-)
-
-// Defines the valid signers
-const (
- V2Signature = iota
- V4Signature = iota
- Route53Signature = iota
-)
-
-// Defines the service endpoint and correct Signer implementation to use
-// to sign requests for this endpoint
-type ServiceInfo struct {
- Endpoint string
- Signer uint
-}
-
-// Region defines the URLs where AWS services may be accessed.
-//
-// See http://goo.gl/d8BP1 for more details.
-type Region struct {
- Name string // the canonical name of this region.
- EC2Endpoint string
- S3Endpoint string
- S3BucketEndpoint string // Not needed by AWS S3. Use ${bucket} for bucket name.
- S3LocationConstraint bool // true if this region requires a LocationConstraint declaration.
- S3LowercaseBucket bool // true if the region requires bucket names to be lower case.
- SDBEndpoint string
- SESEndpoint string
- SNSEndpoint string
- SQSEndpoint string
- IAMEndpoint string
- ELBEndpoint string
- DynamoDBEndpoint string
- CloudWatchServicepoint ServiceInfo
- AutoScalingEndpoint string
- RDSEndpoint ServiceInfo
- STSEndpoint string
- CloudFormationEndpoint string
- ECSEndpoint string
- DynamoDBStreamsEndpoint string
-}
-
-var Regions = map[string]Region{
- APNortheast.Name: APNortheast,
- APSoutheast.Name: APSoutheast,
- APSoutheast2.Name: APSoutheast2,
- EUCentral.Name: EUCentral,
- EUWest.Name: EUWest,
- USEast.Name: USEast,
- USWest.Name: USWest,
- USWest2.Name: USWest2,
- USGovWest.Name: USGovWest,
- SAEast.Name: SAEast,
- CNNorth.Name: CNNorth,
-}
-
-// Designates a signer interface suitable for signing AWS requests, params
-// should be appropriately encoded for the request before signing.
-//
-// A signer should be initialized with Auth and the appropriate endpoint.
-type Signer interface {
- Sign(method, path string, params map[string]string)
-}
-
-// An AWS Service interface with the API to query the AWS service
-//
-// Supplied as an easy way to mock out service calls during testing.
-type AWSService interface {
- // Queries the AWS service at a given method/path with the params and
- // returns an http.Response and error
- Query(method, path string, params map[string]string) (*http.Response, error)
- // Builds an error given an XML payload in the http.Response, can be used
- // to process an error if the status code is not 200 for example.
- BuildError(r *http.Response) error
-}
-
-// Implements a Server Query/Post API to easily query AWS services and build
-// errors when desired
-type Service struct {
- service ServiceInfo
- signer Signer
-}
-
-// Create a base set of params for an action
-func MakeParams(action string) map[string]string {
- params := make(map[string]string)
- params["Action"] = action
- return params
-}
-
-// Create a new AWS server to handle making requests
-func NewService(auth Auth, service ServiceInfo) (s *Service, err error) {
- var signer Signer
- switch service.Signer {
- case V2Signature:
- signer, err = NewV2Signer(auth, service)
- // case V4Signature:
- // signer, err = NewV4Signer(auth, service, Regions["eu-west-1"])
- default:
- err = fmt.Errorf("Unsupported signer for service")
- }
- if err != nil {
- return
- }
- s = &Service{service: service, signer: signer}
- return
-}
-
-func (s *Service) Query(method, path string, params map[string]string) (resp *http.Response, err error) {
- params["Timestamp"] = time.Now().UTC().Format(time.RFC3339)
- u, err := url.Parse(s.service.Endpoint)
- if err != nil {
- return nil, err
- }
- u.Path = path
-
- s.signer.Sign(method, path, params)
- if method == "GET" {
- u.RawQuery = multimap(params).Encode()
- resp, err = http.Get(u.String())
- } else if method == "POST" {
- resp, err = http.PostForm(u.String(), multimap(params))
- }
-
- return
-}
-
-func (s *Service) BuildError(r *http.Response) error {
- errors := ErrorResponse{}
- xml.NewDecoder(r.Body).Decode(&errors)
- var err Error
- err = errors.Errors
- err.RequestId = errors.RequestId
- err.StatusCode = r.StatusCode
- if err.Message == "" {
- err.Message = r.Status
- }
- return &err
-}
-
-type ErrorResponse struct {
- Errors Error `xml:"Error"`
- RequestId string // A unique ID for tracking the request
-}
-
-type Error struct {
- StatusCode int
- Type string
- Code string
- Message string
- RequestId string
-}
-
-func (err *Error) Error() string {
- return fmt.Sprintf("Type: %s, Code: %s, Message: %s",
- err.Type, err.Code, err.Message,
- )
-}
-
-type Auth struct {
- AccessKey, SecretKey string
- token string
- expiration time.Time
-}
-
-func (a *Auth) Token() string {
- if a.token == "" {
- return ""
- }
- if time.Since(a.expiration) >= -30*time.Second { //in an ideal world this should be zero assuming the instance is synching it's clock
- *a, _ = GetAuth("", "", "", time.Time{})
- }
- return a.token
-}
-
-func (a *Auth) Expiration() time.Time {
- return a.expiration
-}
-
-// To be used with other APIs that return auth credentials such as STS
-func NewAuth(accessKey, secretKey, token string, expiration time.Time) *Auth {
- return &Auth{
- AccessKey: accessKey,
- SecretKey: secretKey,
- token: token,
- expiration: expiration,
- }
-}
-
-// ResponseMetadata
-type ResponseMetadata struct {
- RequestId string // A unique ID for tracking the request
-}
-
-type BaseResponse struct {
- ResponseMetadata ResponseMetadata
-}
-
-var unreserved = make([]bool, 128)
-var hex = "0123456789ABCDEF"
-
-func init() {
- // RFC3986
- u := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890-_.~"
- for _, c := range u {
- unreserved[c] = true
- }
-}
-
-func multimap(p map[string]string) url.Values {
- q := make(url.Values, len(p))
- for k, v := range p {
- q[k] = []string{v}
- }
- return q
-}
-
-type credentials struct {
- Code string
- LastUpdated string
- Type string
- AccessKeyId string
- SecretAccessKey string
- Token string
- Expiration string
-}
-
-// GetMetaData retrieves instance metadata about the current machine.
-//
-// See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html for more details.
-func GetMetaData(path string) (contents []byte, err error) {
- url := "http://169.254.169.254/latest/meta-data/" + path
-
- resp, err := RetryingClient.Get(url)
- if err != nil {
- return
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- err = fmt.Errorf("Code %d returned for url %s", resp.StatusCode, url)
- return
- }
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return
- }
- return []byte(body), err
-}
-
-func getInstanceCredentials() (cred credentials, err error) {
- credentialPath := "iam/security-credentials/"
-
- // Get the instance role
- role, err := GetMetaData(credentialPath)
- if err != nil {
- return
- }
-
- // Get the instance role credentials
- credentialJSON, err := GetMetaData(credentialPath + string(role))
- if err != nil {
- return
- }
-
- err = json.Unmarshal([]byte(credentialJSON), &cred)
- return
-}
-
-// GetAuth creates an Auth based on either passed in credentials,
-// environment information or instance based role credentials.
-func GetAuth(accessKey string, secretKey, token string, expiration time.Time) (auth Auth, err error) {
- // First try passed in credentials
- if accessKey != "" && secretKey != "" {
- return Auth{accessKey, secretKey, token, expiration}, nil
- }
-
- // Next try to get auth from the shared credentials file
- auth, err = SharedAuth()
- if err == nil {
- // Found auth, return
- return
- }
-
- // Next try to get auth from the environment
- auth, err = EnvAuth()
- if err == nil {
- // Found auth, return
- return
- }
-
- // Next try getting auth from the instance role
- cred, err := getInstanceCredentials()
- if err == nil {
- // Found auth, return
- auth.AccessKey = cred.AccessKeyId
- auth.SecretKey = cred.SecretAccessKey
- auth.token = cred.Token
- exptdate, err := time.Parse("2006-01-02T15:04:05Z", cred.Expiration)
- if err != nil {
- err = fmt.Errorf("Error Parseing expiration date: cred.Expiration :%s , error: %s \n", cred.Expiration, err)
- }
- auth.expiration = exptdate
- return auth, err
- }
- err = errors.New("No valid AWS authentication found")
- return auth, err
-}
-
-// EnvAuth creates an Auth based on environment information.
-// The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment
-// variables are used.
-// AWS_SESSION_TOKEN is used if present.
-func EnvAuth() (auth Auth, err error) {
- auth.AccessKey = os.Getenv("AWS_ACCESS_KEY_ID")
- if auth.AccessKey == "" {
- auth.AccessKey = os.Getenv("AWS_ACCESS_KEY")
- }
-
- auth.SecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY")
- if auth.SecretKey == "" {
- auth.SecretKey = os.Getenv("AWS_SECRET_KEY")
- }
- if auth.AccessKey == "" {
- err = errors.New("AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment")
- }
- if auth.SecretKey == "" {
- err = errors.New("AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment")
- }
-
- auth.token = os.Getenv("AWS_SESSION_TOKEN")
- return
-}
-
-// SharedAuth creates an Auth based on shared credentials stored in
-// $HOME/.aws/credentials. The AWS_PROFILE environment variables is used to
-// select the profile.
-func SharedAuth() (auth Auth, err error) {
- var profileName = os.Getenv("AWS_PROFILE")
-
- if profileName == "" {
- profileName = "default"
- }
-
- var credentialsFile = os.Getenv("AWS_CREDENTIAL_FILE")
- if credentialsFile == "" {
- var homeDir = os.Getenv("HOME")
- if homeDir == "" {
- err = errors.New("Could not get HOME")
- return
- }
- credentialsFile = homeDir + "/.aws/credentials"
- }
-
- file, err := ini.LoadFile(credentialsFile)
- if err != nil {
- err = errors.New("Couldn't parse AWS credentials file")
- return
- }
-
- var profile = file[profileName]
- if profile == nil {
- err = errors.New("Couldn't find profile in AWS credentials file")
- return
- }
-
- auth.AccessKey = profile["aws_access_key_id"]
- auth.SecretKey = profile["aws_secret_access_key"]
-
- if auth.AccessKey == "" {
- err = errors.New("AWS_ACCESS_KEY_ID not found in environment in credentials file")
- }
- if auth.SecretKey == "" {
- err = errors.New("AWS_SECRET_ACCESS_KEY not found in credentials file")
- }
- return
-}
-
-// Encode takes a string and URI-encodes it in a way suitable
-// to be used in AWS signatures.
-func Encode(s string) string {
- encode := false
- for i := 0; i != len(s); i++ {
- c := s[i]
- if c > 127 || !unreserved[c] {
- encode = true
- break
- }
- }
- if !encode {
- return s
- }
- e := make([]byte, len(s)*3)
- ei := 0
- for i := 0; i != len(s); i++ {
- c := s[i]
- if c > 127 || !unreserved[c] {
- e[ei] = '%'
- e[ei+1] = hex[c>>4]
- e[ei+2] = hex[c&0xF]
- ei += 3
- } else {
- e[ei] = c
- ei += 1
- }
- }
- return string(e[:ei])
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/client.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/client.go
deleted file mode 100644
index 86d2ccec8..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/client.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package aws
-
-import (
- "math"
- "net"
- "net/http"
- "time"
-)
-
-type RetryableFunc func(*http.Request, *http.Response, error) bool
-type WaitFunc func(try int)
-type DeadlineFunc func() time.Time
-
-type ResilientTransport struct {
- // Timeout is the maximum amount of time a dial will wait for
- // a connect to complete.
- //
- // The default is no timeout.
- //
- // With or without a timeout, the operating system may impose
- // its own earlier timeout. For instance, TCP timeouts are
- // often around 3 minutes.
- DialTimeout time.Duration
-
- // MaxTries, if non-zero, specifies the number of times we will retry on
- // failure. Retries are only attempted for temporary network errors or known
- // safe failures.
- MaxTries int
- Deadline DeadlineFunc
- ShouldRetry RetryableFunc
- Wait WaitFunc
- transport *http.Transport
-}
-
-// Convenience method for creating an http client
-func NewClient(rt *ResilientTransport) *http.Client {
- rt.transport = &http.Transport{
- Dial: func(netw, addr string) (net.Conn, error) {
- c, err := net.DialTimeout(netw, addr, rt.DialTimeout)
- if err != nil {
- return nil, err
- }
- c.SetDeadline(rt.Deadline())
- return c, nil
- },
- Proxy: http.ProxyFromEnvironment,
- }
- // TODO: Would be nice is ResilientTransport allowed clients to initialize
- // with http.Transport attributes.
- return &http.Client{
- Transport: rt,
- }
-}
-
-var retryingTransport = &ResilientTransport{
- Deadline: func() time.Time {
- return time.Now().Add(5 * time.Second)
- },
- DialTimeout: 10 * time.Second,
- MaxTries: 3,
- ShouldRetry: awsRetry,
- Wait: ExpBackoff,
-}
-
-// Exported default client
-var RetryingClient = NewClient(retryingTransport)
-
-func (t *ResilientTransport) RoundTrip(req *http.Request) (*http.Response, error) {
- return t.tries(req)
-}
-
-// Retry a request a maximum of t.MaxTries times.
-// We'll only retry if the proper criteria are met.
-// If a wait function is specified, wait that amount of time
-// In between requests.
-func (t *ResilientTransport) tries(req *http.Request) (res *http.Response, err error) {
- for try := 0; try < t.MaxTries; try += 1 {
- res, err = t.transport.RoundTrip(req)
-
- if !t.ShouldRetry(req, res, err) {
- break
- }
- if res != nil {
- res.Body.Close()
- }
- if t.Wait != nil {
- t.Wait(try)
- }
- }
-
- return
-}
-
-func ExpBackoff(try int) {
- time.Sleep(100 * time.Millisecond *
- time.Duration(math.Exp2(float64(try))))
-}
-
-func LinearBackoff(try int) {
- time.Sleep(time.Duration(try*100) * time.Millisecond)
-}
-
-// Decide if we should retry a request.
-// In general, the criteria for retrying a request is described here
-// http://docs.aws.amazon.com/general/latest/gr/api-retries.html
-func awsRetry(req *http.Request, res *http.Response, err error) bool {
- retry := false
-
- // Retry if there's a temporary network error.
- if neterr, ok := err.(net.Error); ok {
- if neterr.Temporary() {
- retry = true
- }
- }
-
- // Retry if we get a 5xx series error.
- if res != nil {
- if res.StatusCode >= 500 && res.StatusCode < 600 {
- retry = true
- }
- }
-
- return retry
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/regions.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/regions.go
deleted file mode 100644
index 5e18f023d..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/regions.go
+++ /dev/null
@@ -1,254 +0,0 @@
-package aws
-
-var USGovWest = Region{
- "us-gov-west-1",
- "https://ec2.us-gov-west-1.amazonaws.com",
- "https://s3-fips-us-gov-west-1.amazonaws.com",
- "",
- true,
- true,
- "",
- "",
- "https://sns.us-gov-west-1.amazonaws.com",
- "https://sqs.us-gov-west-1.amazonaws.com",
- "https://iam.us-gov.amazonaws.com",
- "https://elasticloadbalancing.us-gov-west-1.amazonaws.com",
- "https://dynamodb.us-gov-west-1.amazonaws.com",
- ServiceInfo{"https://monitoring.us-gov-west-1.amazonaws.com", V2Signature},
- "https://autoscaling.us-gov-west-1.amazonaws.com",
- ServiceInfo{"https://rds.us-gov-west-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.us-gov-west-1.amazonaws.com",
- "https://ecs.us-gov-west-1.amazonaws.com",
- "https://streams.dynamodb.us-gov-west-1.amazonaws.com",
-}
-
-var USEast = Region{
- "us-east-1",
- "https://ec2.us-east-1.amazonaws.com",
- "https://s3.amazonaws.com",
- "",
- false,
- false,
- "https://sdb.amazonaws.com",
- "https://email.us-east-1.amazonaws.com",
- "https://sns.us-east-1.amazonaws.com",
- "https://sqs.us-east-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.us-east-1.amazonaws.com",
- "https://dynamodb.us-east-1.amazonaws.com",
- ServiceInfo{"https://monitoring.us-east-1.amazonaws.com", V2Signature},
- "https://autoscaling.us-east-1.amazonaws.com",
- ServiceInfo{"https://rds.us-east-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.us-east-1.amazonaws.com",
- "https://ecs.us-east-1.amazonaws.com",
- "https://streams.dynamodb.us-east-1.amazonaws.com",
-}
-
-var USWest = Region{
- "us-west-1",
- "https://ec2.us-west-1.amazonaws.com",
- "https://s3-us-west-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.us-west-1.amazonaws.com",
- "",
- "https://sns.us-west-1.amazonaws.com",
- "https://sqs.us-west-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.us-west-1.amazonaws.com",
- "https://dynamodb.us-west-1.amazonaws.com",
- ServiceInfo{"https://monitoring.us-west-1.amazonaws.com", V2Signature},
- "https://autoscaling.us-west-1.amazonaws.com",
- ServiceInfo{"https://rds.us-west-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.us-west-1.amazonaws.com",
- "https://ecs.us-west-1.amazonaws.com",
- "https://streams.dynamodb.us-west-1.amazonaws.com",
-}
-
-var USWest2 = Region{
- "us-west-2",
- "https://ec2.us-west-2.amazonaws.com",
- "https://s3-us-west-2.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.us-west-2.amazonaws.com",
- "https://email.us-west-2.amazonaws.com",
- "https://sns.us-west-2.amazonaws.com",
- "https://sqs.us-west-2.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.us-west-2.amazonaws.com",
- "https://dynamodb.us-west-2.amazonaws.com",
- ServiceInfo{"https://monitoring.us-west-2.amazonaws.com", V2Signature},
- "https://autoscaling.us-west-2.amazonaws.com",
- ServiceInfo{"https://rds.us-west-2.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.us-west-2.amazonaws.com",
- "https://ecs.us-west-2.amazonaws.com",
- "https://streams.dynamodb.us-west-2.amazonaws.com",
-}
-
-var EUWest = Region{
- "eu-west-1",
- "https://ec2.eu-west-1.amazonaws.com",
- "https://s3-eu-west-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.eu-west-1.amazonaws.com",
- "https://email.eu-west-1.amazonaws.com",
- "https://sns.eu-west-1.amazonaws.com",
- "https://sqs.eu-west-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.eu-west-1.amazonaws.com",
- "https://dynamodb.eu-west-1.amazonaws.com",
- ServiceInfo{"https://monitoring.eu-west-1.amazonaws.com", V2Signature},
- "https://autoscaling.eu-west-1.amazonaws.com",
- ServiceInfo{"https://rds.eu-west-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.eu-west-1.amazonaws.com",
- "https://ecs.eu-west-1.amazonaws.com",
- "https://streams.dynamodb.eu-west-1.amazonaws.com",
-}
-
-var EUCentral = Region{
- "eu-central-1",
- "https://ec2.eu-central-1.amazonaws.com",
- "https://s3-eu-central-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.eu-central-1.amazonaws.com",
- "https://email.eu-central-1.amazonaws.com",
- "https://sns.eu-central-1.amazonaws.com",
- "https://sqs.eu-central-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.eu-central-1.amazonaws.com",
- "https://dynamodb.eu-central-1.amazonaws.com",
- ServiceInfo{"https://monitoring.eu-central-1.amazonaws.com", V2Signature},
- "https://autoscaling.eu-central-1.amazonaws.com",
- ServiceInfo{"https://rds.eu-central-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.eu-central-1.amazonaws.com",
- "https://ecs.eu-central-1.amazonaws.com",
- "https://streams.dynamodb.eu-central-1.amazonaws.com",
-}
-
-var APSoutheast = Region{
- "ap-southeast-1",
- "https://ec2.ap-southeast-1.amazonaws.com",
- "https://s3-ap-southeast-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.ap-southeast-1.amazonaws.com",
- "",
- "https://sns.ap-southeast-1.amazonaws.com",
- "https://sqs.ap-southeast-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.ap-southeast-1.amazonaws.com",
- "https://dynamodb.ap-southeast-1.amazonaws.com",
- ServiceInfo{"https://monitoring.ap-southeast-1.amazonaws.com", V2Signature},
- "https://autoscaling.ap-southeast-1.amazonaws.com",
- ServiceInfo{"https://rds.ap-southeast-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.ap-southeast-1.amazonaws.com",
- "https://ecs.ap-southeast-1.amazonaws.com",
- "https://streams.dynamodb.ap-southeast-1.amazonaws.com",
-}
-
-var APSoutheast2 = Region{
- "ap-southeast-2",
- "https://ec2.ap-southeast-2.amazonaws.com",
- "https://s3-ap-southeast-2.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.ap-southeast-2.amazonaws.com",
- "",
- "https://sns.ap-southeast-2.amazonaws.com",
- "https://sqs.ap-southeast-2.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.ap-southeast-2.amazonaws.com",
- "https://dynamodb.ap-southeast-2.amazonaws.com",
- ServiceInfo{"https://monitoring.ap-southeast-2.amazonaws.com", V2Signature},
- "https://autoscaling.ap-southeast-2.amazonaws.com",
- ServiceInfo{"https://rds.ap-southeast-2.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.ap-southeast-2.amazonaws.com",
- "https://ecs.ap-southeast-2.amazonaws.com",
- "https://streams.dynamodb.ap-southeast-2.amazonaws.com",
-}
-
-var APNortheast = Region{
- "ap-northeast-1",
- "https://ec2.ap-northeast-1.amazonaws.com",
- "https://s3-ap-northeast-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.ap-northeast-1.amazonaws.com",
- "",
- "https://sns.ap-northeast-1.amazonaws.com",
- "https://sqs.ap-northeast-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.ap-northeast-1.amazonaws.com",
- "https://dynamodb.ap-northeast-1.amazonaws.com",
- ServiceInfo{"https://monitoring.ap-northeast-1.amazonaws.com", V2Signature},
- "https://autoscaling.ap-northeast-1.amazonaws.com",
- ServiceInfo{"https://rds.ap-northeast-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.ap-northeast-1.amazonaws.com",
- "https://ecs.ap-northeast-1.amazonaws.com",
- "https://streams.dynamodb.ap-northeast-1.amazonaws.com",
-}
-
-var SAEast = Region{
- "sa-east-1",
- "https://ec2.sa-east-1.amazonaws.com",
- "https://s3-sa-east-1.amazonaws.com",
- "",
- true,
- true,
- "https://sdb.sa-east-1.amazonaws.com",
- "",
- "https://sns.sa-east-1.amazonaws.com",
- "https://sqs.sa-east-1.amazonaws.com",
- "https://iam.amazonaws.com",
- "https://elasticloadbalancing.sa-east-1.amazonaws.com",
- "https://dynamodb.sa-east-1.amazonaws.com",
- ServiceInfo{"https://monitoring.sa-east-1.amazonaws.com", V2Signature},
- "https://autoscaling.sa-east-1.amazonaws.com",
- ServiceInfo{"https://rds.sa-east-1.amazonaws.com", V2Signature},
- "https://sts.amazonaws.com",
- "https://cloudformation.sa-east-1.amazonaws.com",
- "https://ecs.sa-east-1.amazonaws.com",
- "https://streams.dynamodb.sa-east-1.amazonaws.com",
-}
-
-var CNNorth = Region{
- "cn-north-1",
- "https://ec2.cn-north-1.amazonaws.com.cn",
- "https://s3.cn-north-1.amazonaws.com.cn",
- "",
- true,
- true,
- "https://sdb.cn-north-1.amazonaws.com.cn",
- "",
- "https://sns.cn-north-1.amazonaws.com.cn",
- "https://sqs.cn-north-1.amazonaws.com.cn",
- "https://iam.cn-north-1.amazonaws.com.cn",
- "https://elasticloadbalancing.cn-north-1.amazonaws.com.cn",
- "https://dynamodb.cn-north-1.amazonaws.com.cn",
- ServiceInfo{"https://monitoring.cn-north-1.amazonaws.com.cn", V4Signature},
- "https://autoscaling.cn-north-1.amazonaws.com.cn",
- ServiceInfo{"https://rds.cn-north-1.amazonaws.com.cn", V4Signature},
- "https://sts.cn-north-1.amazonaws.com.cn",
- "https://cloudformation.cn-north-1.amazonaws.com.cn",
- "https://ecs.cn-north-1.amazonaws.com.cn",
- "https://streams.dynamodb.cn-north-1.amazonaws.com.cn",
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign.go
deleted file mode 100644
index 5cf990525..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign.go
+++ /dev/null
@@ -1,357 +0,0 @@
-package aws
-
-import (
- "bytes"
- "crypto/hmac"
- "crypto/sha256"
- "encoding/base64"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/url"
- "path"
- "sort"
- "strings"
- "time"
-)
-
-type V2Signer struct {
- auth Auth
- service ServiceInfo
- host string
-}
-
-var b64 = base64.StdEncoding
-
-func NewV2Signer(auth Auth, service ServiceInfo) (*V2Signer, error) {
- u, err := url.Parse(service.Endpoint)
- if err != nil {
- return nil, err
- }
- return &V2Signer{auth: auth, service: service, host: u.Host}, nil
-}
-
-func (s *V2Signer) Sign(method, path string, params map[string]string) {
- params["AWSAccessKeyId"] = s.auth.AccessKey
- params["SignatureVersion"] = "2"
- params["SignatureMethod"] = "HmacSHA256"
- if s.auth.Token() != "" {
- params["SecurityToken"] = s.auth.Token()
- }
-
- // AWS specifies that the parameters in a signed request must
- // be provided in the natural order of the keys. This is distinct
- // from the natural order of the encoded value of key=value.
- // Percent and Equals affect the sorting order.
- var keys, sarray []string
- for k, _ := range params {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, k := range keys {
- sarray = append(sarray, Encode(k)+"="+Encode(params[k]))
- }
- joined := strings.Join(sarray, "&")
- payload := method + "\n" + s.host + "\n" + path + "\n" + joined
- hash := hmac.New(sha256.New, []byte(s.auth.SecretKey))
- hash.Write([]byte(payload))
- signature := make([]byte, b64.EncodedLen(hash.Size()))
- b64.Encode(signature, hash.Sum(nil))
-
- params["Signature"] = string(signature)
-}
-
-// Common date formats for signing requests
-const (
- ISO8601BasicFormat = "20060102T150405Z"
- ISO8601BasicFormatShort = "20060102"
-)
-
-type Route53Signer struct {
- auth Auth
-}
-
-func NewRoute53Signer(auth Auth) *Route53Signer {
- return &Route53Signer{auth: auth}
-}
-
-// getCurrentDate fetches the date stamp from the aws servers to
-// ensure the auth headers are within 5 minutes of the server time
-func (s *Route53Signer) getCurrentDate() string {
- response, err := http.Get("https://route53.amazonaws.com/date")
- if err != nil {
- fmt.Print("Unable to get date from amazon: ", err)
- return ""
- }
-
- response.Body.Close()
- return response.Header.Get("Date")
-}
-
-// Creates the authorize signature based on the date stamp and secret key
-func (s *Route53Signer) getHeaderAuthorize(message string) string {
- hmacSha256 := hmac.New(sha256.New, []byte(s.auth.SecretKey))
- hmacSha256.Write([]byte(message))
- cryptedString := hmacSha256.Sum(nil)
-
- return base64.StdEncoding.EncodeToString(cryptedString)
-}
-
-// Adds all the required headers for AWS Route53 API to the request
-// including the authorization
-func (s *Route53Signer) Sign(req *http.Request) {
- date := s.getCurrentDate()
- authHeader := fmt.Sprintf("AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=%s,Signature=%s",
- s.auth.AccessKey, "HmacSHA256", s.getHeaderAuthorize(date))
-
- req.Header.Set("Host", req.Host)
- req.Header.Set("X-Amzn-Authorization", authHeader)
- req.Header.Set("X-Amz-Date", date)
- req.Header.Set("Content-Type", "application/xml")
-}
-
-/*
-The V4Signer encapsulates all of the functionality to sign a request with the AWS
-Signature Version 4 Signing Process. (http://goo.gl/u1OWZz)
-*/
-type V4Signer struct {
- auth Auth
- serviceName string
- region Region
-}
-
-/*
-Return a new instance of a V4Signer capable of signing AWS requests.
-*/
-func NewV4Signer(auth Auth, serviceName string, region Region) *V4Signer {
- return &V4Signer{auth: auth, serviceName: serviceName, region: region}
-}
-
-/*
-Sign a request according to the AWS Signature Version 4 Signing Process. (http://goo.gl/u1OWZz)
-
-The signed request will include an "x-amz-date" header with a current timestamp if a valid "x-amz-date"
-or "date" header was not available in the original request. In addition, AWS Signature Version 4 requires
-the "host" header to be a signed header, therefor the Sign method will manually set a "host" header from
-the request.Host.
-
-The signed request will include a new "Authorization" header indicating that the request has been signed.
-
-Any changes to the request after signing the request will invalidate the signature.
-*/
-func (s *V4Signer) Sign(req *http.Request) {
- req.Header.Set("host", req.Host) // host header must be included as a signed header
- t := s.requestTime(req) // Get requst time
- creq := s.canonicalRequest(req) // Build canonical request
- sts := s.stringToSign(t, creq) // Build string to sign
- signature := s.signature(t, sts) // Calculate the AWS Signature Version 4
- auth := s.authorization(req.Header, t, signature) // Create Authorization header value
- req.Header.Set("Authorization", auth) // Add Authorization header to request
- return
-}
-
-/*
-requestTime method will parse the time from the request "x-amz-date" or "date" headers.
-If the "x-amz-date" header is present, that will take priority over the "date" header.
-If neither header is defined or we are unable to parse either header as a valid date
-then we will create a new "x-amz-date" header with the current time.
-*/
-func (s *V4Signer) requestTime(req *http.Request) time.Time {
-
- // Get "x-amz-date" header
- date := req.Header.Get("x-amz-date")
-
- // Attempt to parse as ISO8601BasicFormat
- t, err := time.Parse(ISO8601BasicFormat, date)
- if err == nil {
- return t
- }
-
- // Attempt to parse as http.TimeFormat
- t, err = time.Parse(http.TimeFormat, date)
- if err == nil {
- req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
- return t
- }
-
- // Get "date" header
- date = req.Header.Get("date")
-
- // Attempt to parse as http.TimeFormat
- t, err = time.Parse(http.TimeFormat, date)
- if err == nil {
- return t
- }
-
- // Create a current time header to be used
- t = time.Now().UTC()
- req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
- return t
-}
-
-/*
-canonicalRequest method creates the canonical request according to Task 1 of the AWS Signature Version 4 Signing Process. (http://goo.gl/eUUZ3S)
-
- CanonicalRequest =
- HTTPRequestMethod + '\n' +
- CanonicalURI + '\n' +
- CanonicalQueryString + '\n' +
- CanonicalHeaders + '\n' +
- SignedHeaders + '\n' +
- HexEncode(Hash(Payload))
-*/
-func (s *V4Signer) canonicalRequest(req *http.Request) string {
- c := new(bytes.Buffer)
- fmt.Fprintf(c, "%s\n", req.Method)
- fmt.Fprintf(c, "%s\n", s.canonicalURI(req.URL))
- fmt.Fprintf(c, "%s\n", s.canonicalQueryString(req.URL))
- fmt.Fprintf(c, "%s\n\n", s.canonicalHeaders(req.Header))
- fmt.Fprintf(c, "%s\n", s.signedHeaders(req.Header))
- fmt.Fprintf(c, "%s", s.payloadHash(req))
- return c.String()
-}
-
-func (s *V4Signer) canonicalURI(u *url.URL) string {
- canonicalPath := u.RequestURI()
- if u.RawQuery != "" {
- canonicalPath = canonicalPath[:len(canonicalPath)-len(u.RawQuery)-1]
- }
- slash := strings.HasSuffix(canonicalPath, "/")
- canonicalPath = path.Clean(canonicalPath)
- if canonicalPath != "/" && slash {
- canonicalPath += "/"
- }
- return canonicalPath
-}
-
-func (s *V4Signer) canonicalQueryString(u *url.URL) string {
- var a []string
- for k, vs := range u.Query() {
- k = url.QueryEscape(k)
- for _, v := range vs {
- if v == "" {
- a = append(a, k+"=")
- } else {
- v = url.QueryEscape(v)
- a = append(a, k+"="+v)
- }
- }
- }
- sort.Strings(a)
- return strings.Join(a, "&")
-}
-
-func (s *V4Signer) canonicalHeaders(h http.Header) string {
- i, a := 0, make([]string, len(h))
- for k, v := range h {
- for j, w := range v {
- v[j] = strings.Trim(w, " ")
- }
- sort.Strings(v)
- a[i] = strings.ToLower(k) + ":" + strings.Join(v, ",")
- i++
- }
- sort.Strings(a)
- return strings.Join(a, "\n")
-}
-
-func (s *V4Signer) signedHeaders(h http.Header) string {
- i, a := 0, make([]string, len(h))
- for k, _ := range h {
- a[i] = strings.ToLower(k)
- i++
- }
- sort.Strings(a)
- return strings.Join(a, ";")
-}
-
-func (s *V4Signer) payloadHash(req *http.Request) string {
- var b []byte
- if req.Body == nil {
- b = []byte("")
- } else {
- var err error
- b, err = ioutil.ReadAll(req.Body)
- if err != nil {
- // TODO: I REALLY DON'T LIKE THIS PANIC!!!!
- panic(err)
- }
- }
- req.Body = ioutil.NopCloser(bytes.NewBuffer(b))
- return s.hash(string(b))
-}
-
-/*
-stringToSign method creates the string to sign accorting to Task 2 of the AWS Signature Version 4 Signing Process. (http://goo.gl/es1PAu)
-
- StringToSign =
- Algorithm + '\n' +
- RequestDate + '\n' +
- CredentialScope + '\n' +
- HexEncode(Hash(CanonicalRequest))
-*/
-func (s *V4Signer) stringToSign(t time.Time, creq string) string {
- w := new(bytes.Buffer)
- fmt.Fprint(w, "AWS4-HMAC-SHA256\n")
- fmt.Fprintf(w, "%s\n", t.Format(ISO8601BasicFormat))
- fmt.Fprintf(w, "%s\n", s.credentialScope(t))
- fmt.Fprintf(w, "%s", s.hash(creq))
- return w.String()
-}
-
-func (s *V4Signer) credentialScope(t time.Time) string {
- return fmt.Sprintf("%s/%s/%s/aws4_request", t.Format(ISO8601BasicFormatShort), s.region.Name, s.serviceName)
-}
-
-/*
-signature method calculates the AWS Signature Version 4 according to Task 3 of the AWS Signature Version 4 Signing Process. (http://goo.gl/j0Yqe1)
-
- signature = HexEncode(HMAC(derived-signing-key, string-to-sign))
-*/
-func (s *V4Signer) signature(t time.Time, sts string) string {
- h := s.hmac(s.derivedKey(t), []byte(sts))
- return fmt.Sprintf("%x", h)
-}
-
-/*
-derivedKey method derives a signing key to be used for signing a request.
-
- kSecret = Your AWS Secret Access Key
- kDate = HMAC("AWS4" + kSecret, Date)
- kRegion = HMAC(kDate, Region)
- kService = HMAC(kRegion, Service)
- kSigning = HMAC(kService, "aws4_request")
-*/
-func (s *V4Signer) derivedKey(t time.Time) []byte {
- h := s.hmac([]byte("AWS4"+s.auth.SecretKey), []byte(t.Format(ISO8601BasicFormatShort)))
- h = s.hmac(h, []byte(s.region.Name))
- h = s.hmac(h, []byte(s.serviceName))
- h = s.hmac(h, []byte("aws4_request"))
- return h
-}
-
-/*
-authorization method generates the authorization header value.
-*/
-func (s *V4Signer) authorization(header http.Header, t time.Time, signature string) string {
- w := new(bytes.Buffer)
- fmt.Fprint(w, "AWS4-HMAC-SHA256 ")
- fmt.Fprintf(w, "Credential=%s/%s, ", s.auth.AccessKey, s.credentialScope(t))
- fmt.Fprintf(w, "SignedHeaders=%s, ", s.signedHeaders(header))
- fmt.Fprintf(w, "Signature=%s", signature)
- return w.String()
-}
-
-// hash method calculates the sha256 hash for a given string
-func (s *V4Signer) hash(in string) string {
- h := sha256.New()
- fmt.Fprintf(h, "%s", in)
- return fmt.Sprintf("%x", h.Sum(nil))
-}
-
-// hmac method calculates the sha256 hmac for a given slice of bytes
-func (s *V4Signer) hmac(key, data []byte) []byte {
- h := hmac.New(sha256.New, key)
- h.Write(data)
- return h.Sum(nil)
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi.go
deleted file mode 100644
index 348ead300..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi.go
+++ /dev/null
@@ -1,439 +0,0 @@
-package s3
-
-import (
- "bytes"
- "crypto/md5"
- "encoding/base64"
- "encoding/hex"
- "encoding/xml"
- "errors"
- "io"
- "sort"
- "strconv"
-)
-
-// Multi represents an unfinished multipart upload.
-//
-// Multipart uploads allow sending big objects in smaller chunks.
-// After all parts have been sent, the upload must be explicitly
-// completed by calling Complete with the list of parts.
-//
-// See http://goo.gl/vJfTG for an overview of multipart uploads.
-type Multi struct {
- Bucket *Bucket
- Key string
- UploadId string
-}
-
-// That's the default. Here just for testing.
-var listMultiMax = 1000
-
-type listMultiResp struct {
- NextKeyMarker string
- NextUploadIdMarker string
- IsTruncated bool
- Upload []Multi
- CommonPrefixes []string `xml:"CommonPrefixes>Prefix"`
-}
-
-// ListMulti returns the list of unfinished multipart uploads in b.
-//
-// The prefix parameter limits the response to keys that begin with the
-// specified prefix. You can use prefixes to separate a bucket into different
-// groupings of keys (to get the feeling of folders, for example).
-//
-// The delim parameter causes the response to group all of the keys that
-// share a common prefix up to the next delimiter in a single entry within
-// the CommonPrefixes field. You can use delimiters to separate a bucket
-// into different groupings of keys, similar to how folders would work.
-//
-// See http://goo.gl/ePioY for details.
-func (b *Bucket) ListMulti(prefix, delim string) (multis []*Multi, prefixes []string, err error) {
- params := map[string][]string{
- "uploads": {""},
- "max-uploads": {strconv.FormatInt(int64(listMultiMax), 10)},
- "prefix": {prefix},
- "delimiter": {delim},
- }
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- req := &request{
- method: "GET",
- bucket: b.Name,
- params: params,
- }
- var resp listMultiResp
- err := b.S3.query(req, &resp)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err != nil {
- return nil, nil, err
- }
- for i := range resp.Upload {
- multi := &resp.Upload[i]
- multi.Bucket = b
- multis = append(multis, multi)
- }
- prefixes = append(prefixes, resp.CommonPrefixes...)
- if !resp.IsTruncated {
- return multis, prefixes, nil
- }
- params["key-marker"] = []string{resp.NextKeyMarker}
- params["upload-id-marker"] = []string{resp.NextUploadIdMarker}
- attempt = b.S3.AttemptStrategy.Start() // Last request worked.
- }
- panic("unreachable")
-}
-
-// Multi returns a multipart upload handler for the provided key
-// inside b. If a multipart upload exists for key, it is returned,
-// otherwise a new multipart upload is initiated with contType and perm.
-func (b *Bucket) Multi(key, contType string, perm ACL) (*Multi, error) {
- multis, _, err := b.ListMulti(key, "")
- if err != nil && !hasCode(err, "NoSuchUpload") {
- return nil, err
- }
- for _, m := range multis {
- if m.Key == key {
- return m, nil
- }
- }
- return b.InitMulti(key, contType, perm)
-}
-
-// InitMulti initializes a new multipart upload at the provided
-// key inside b and returns a value for manipulating it.
-//
-// See http://goo.gl/XP8kL for details.
-func (b *Bucket) InitMulti(key string, contType string, perm ACL) (*Multi, error) {
- headers := map[string][]string{
- "Content-Type": {contType},
- "Content-Length": {"0"},
- "x-amz-acl": {string(perm)},
- }
- params := map[string][]string{
- "uploads": {""},
- }
- req := &request{
- method: "POST",
- bucket: b.Name,
- path: key,
- headers: headers,
- params: params,
- }
- var err error
- var resp struct {
- UploadId string `xml:"UploadId"`
- }
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- err = b.S3.query(req, &resp)
- if !shouldRetry(err) {
- break
- }
- }
- if err != nil {
- return nil, err
- }
- return &Multi{Bucket: b, Key: key, UploadId: resp.UploadId}, nil
-}
-
-// PutPart sends part n of the multipart upload, reading all the content from r.
-// Each part, except for the last one, must be at least 5MB in size.
-//
-// See http://goo.gl/pqZer for details.
-func (m *Multi) PutPart(n int, r io.ReadSeeker) (Part, error) {
- partSize, _, md5b64, err := seekerInfo(r)
- if err != nil {
- return Part{}, err
- }
- return m.putPart(n, r, partSize, md5b64)
-}
-
-func (m *Multi) putPart(n int, r io.ReadSeeker, partSize int64, md5b64 string) (Part, error) {
- headers := map[string][]string{
- "Content-Length": {strconv.FormatInt(partSize, 10)},
- "Content-MD5": {md5b64},
- }
- params := map[string][]string{
- "uploadId": {m.UploadId},
- "partNumber": {strconv.FormatInt(int64(n), 10)},
- }
- for attempt := m.Bucket.S3.AttemptStrategy.Start(); attempt.Next(); {
- _, err := r.Seek(0, 0)
- if err != nil {
- return Part{}, err
- }
- req := &request{
- method: "PUT",
- bucket: m.Bucket.Name,
- path: m.Key,
- headers: headers,
- params: params,
- payload: r,
- }
- err = m.Bucket.S3.prepare(req)
- if err != nil {
- return Part{}, err
- }
- resp, err := m.Bucket.S3.run(req, nil)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err != nil {
- return Part{}, err
- }
- etag := resp.Header.Get("ETag")
- if etag == "" {
- return Part{}, errors.New("part upload succeeded with no ETag")
- }
- return Part{n, etag, partSize}, nil
- }
- panic("unreachable")
-}
-
-func seekerInfo(r io.ReadSeeker) (size int64, md5hex string, md5b64 string, err error) {
- _, err = r.Seek(0, 0)
- if err != nil {
- return 0, "", "", err
- }
- digest := md5.New()
- size, err = io.Copy(digest, r)
- if err != nil {
- return 0, "", "", err
- }
- sum := digest.Sum(nil)
- md5hex = hex.EncodeToString(sum)
- md5b64 = base64.StdEncoding.EncodeToString(sum)
- return size, md5hex, md5b64, nil
-}
-
-type Part struct {
- N int `xml:"PartNumber"`
- ETag string
- Size int64
-}
-
-type partSlice []Part
-
-func (s partSlice) Len() int { return len(s) }
-func (s partSlice) Less(i, j int) bool { return s[i].N < s[j].N }
-func (s partSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-type listPartsResp struct {
- NextPartNumberMarker string
- IsTruncated bool
- Part []Part
-}
-
-// That's the default. Here just for testing.
-var listPartsMax = 1000
-
-// ListParts returns the list of previously uploaded parts in m,
-// ordered by part number.
-//
-// See http://goo.gl/ePioY for details.
-func (m *Multi) ListParts() ([]Part, error) {
- params := map[string][]string{
- "uploadId": {m.UploadId},
- "max-parts": {strconv.FormatInt(int64(listPartsMax), 10)},
- }
- var parts partSlice
- for attempt := m.Bucket.S3.AttemptStrategy.Start(); attempt.Next(); {
- req := &request{
- method: "GET",
- bucket: m.Bucket.Name,
- path: m.Key,
- params: params,
- }
- var resp listPartsResp
- err := m.Bucket.S3.query(req, &resp)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err != nil {
- return nil, err
- }
- parts = append(parts, resp.Part...)
- if !resp.IsTruncated {
- sort.Sort(parts)
- return parts, nil
- }
- params["part-number-marker"] = []string{resp.NextPartNumberMarker}
- attempt = m.Bucket.S3.AttemptStrategy.Start() // Last request worked.
- }
- panic("unreachable")
-}
-
-type ReaderAtSeeker interface {
- io.ReaderAt
- io.ReadSeeker
-}
-
-// PutAll sends all of r via a multipart upload with parts no larger
-// than partSize bytes, which must be set to at least 5MB.
-// Parts previously uploaded are either reused if their checksum
-// and size match the new part, or otherwise overwritten with the
-// new content.
-// PutAll returns all the parts of m (reused or not).
-func (m *Multi) PutAll(r ReaderAtSeeker, partSize int64) ([]Part, error) {
- old, err := m.ListParts()
- if err != nil && !hasCode(err, "NoSuchUpload") {
- return nil, err
- }
- reuse := 0 // Index of next old part to consider reusing.
- current := 1 // Part number of latest good part handled.
- totalSize, err := r.Seek(0, 2)
- if err != nil {
- return nil, err
- }
- first := true // Must send at least one empty part if the file is empty.
- var result []Part
-NextSection:
- for offset := int64(0); offset < totalSize || first; offset += partSize {
- first = false
- if offset+partSize > totalSize {
- partSize = totalSize - offset
- }
- section := io.NewSectionReader(r, offset, partSize)
- _, md5hex, md5b64, err := seekerInfo(section)
- if err != nil {
- return nil, err
- }
- for reuse < len(old) && old[reuse].N <= current {
- // Looks like this part was already sent.
- part := &old[reuse]
- etag := `"` + md5hex + `"`
- if part.N == current && part.Size == partSize && part.ETag == etag {
- // Checksum matches. Reuse the old part.
- result = append(result, *part)
- current++
- continue NextSection
- }
- reuse++
- }
-
- // Part wasn't found or doesn't match. Send it.
- part, err := m.putPart(current, section, partSize, md5b64)
- if err != nil {
- return nil, err
- }
- result = append(result, part)
- current++
- }
- return result, nil
-}
-
-type completeUpload struct {
- XMLName xml.Name `xml:"CompleteMultipartUpload"`
- Parts completeParts `xml:"Part"`
-}
-
-type completePart struct {
- PartNumber int
- ETag string
-}
-
-type completeParts []completePart
-
-func (p completeParts) Len() int { return len(p) }
-func (p completeParts) Less(i, j int) bool { return p[i].PartNumber < p[j].PartNumber }
-func (p completeParts) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-
-type completeResponse struct {
- // The element name: should be either CompleteMultipartUploadResult or Error.
- XMLName xml.Name
- // If the element was error, then it should have the following:
- Code string
- Message string
- RequestId string
- HostId string
-}
-
-// Complete assembles the given previously uploaded parts into the
-// final object. This operation may take several minutes.
-//
-// The complete call to AMZ may still fail after returning HTTP 200,
-// so even though it's unusued, the body of the reply must be demarshalled
-// and checked to see whether or not the complete succeeded.
-//
-// See http://goo.gl/2Z7Tw for details.
-func (m *Multi) Complete(parts []Part) error {
- params := map[string][]string{
- "uploadId": {m.UploadId},
- }
- c := completeUpload{}
- for _, p := range parts {
- c.Parts = append(c.Parts, completePart{p.N, p.ETag})
- }
- sort.Sort(c.Parts)
- data, err := xml.Marshal(&c)
- if err != nil {
- return err
- }
-
- // Setting Content-Length prevents breakage on DreamObjects
- for attempt := m.Bucket.S3.AttemptStrategy.Start(); attempt.Next(); {
- req := &request{
- method: "POST",
- bucket: m.Bucket.Name,
- path: m.Key,
- params: params,
- payload: bytes.NewReader(data),
- headers: map[string][]string{
- "Content-Length": []string{strconv.Itoa(len(data))},
- },
- }
-
- resp := &completeResponse{}
- err := m.Bucket.S3.query(req, resp)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err == nil && resp.XMLName.Local == "Error" {
- err = &Error{
- StatusCode: 200,
- Code: resp.Code,
- Message: resp.Message,
- RequestId: resp.RequestId,
- HostId: resp.HostId,
- }
- }
- return err
- }
- panic("unreachable")
-}
-
-// Abort deletes an unifinished multipart upload and any previously
-// uploaded parts for it.
-//
-// After a multipart upload is aborted, no additional parts can be
-// uploaded using it. However, if any part uploads are currently in
-// progress, those part uploads might or might not succeed. As a result,
-// it might be necessary to abort a given multipart upload multiple
-// times in order to completely free all storage consumed by all parts.
-//
-// NOTE: If the described scenario happens to you, please report back to
-// the goamz authors with details. In the future such retrying should be
-// handled internally, but it's not clear what happens precisely (Is an
-// error returned? Is the issue completely undetectable?).
-//
-// See http://goo.gl/dnyJw for details.
-func (m *Multi) Abort() error {
- params := map[string][]string{
- "uploadId": {m.UploadId},
- }
- for attempt := m.Bucket.S3.AttemptStrategy.Start(); attempt.Next(); {
- req := &request{
- method: "DELETE",
- bucket: m.Bucket.Name,
- path: m.Key,
- params: params,
- }
- err := m.Bucket.S3.query(req, nil)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- return err
- }
- panic("unreachable")
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3.go
deleted file mode 100644
index 9490c9b96..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3.go
+++ /dev/null
@@ -1,1155 +0,0 @@
-//
-// goamz - Go packages to interact with the Amazon Web Services.
-//
-// https://wiki.ubuntu.com/goamz
-//
-// Copyright (c) 2011 Canonical Ltd.
-//
-// Written by Gustavo Niemeyer <gustavo.niemeyer@canonical.com>
-//
-
-package s3
-
-import (
- "bytes"
- "crypto/hmac"
- "crypto/md5"
- "crypto/sha1"
- "encoding/base64"
- "encoding/xml"
- "fmt"
- "github.com/goamz/goamz/aws"
- "io"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/http/httputil"
- "net/url"
- "strconv"
- "strings"
- "time"
-)
-
-const debug = false
-
-// The S3 type encapsulates operations with an S3 region.
-type S3 struct {
- aws.Auth
- aws.Region
-
- // ConnectTimeout is the maximum time a request attempt will
- // wait for a successful connection to be made.
- //
- // A value of zero means no timeout.
- ConnectTimeout time.Duration
-
- // ReadTimeout is the maximum time a request attempt will wait
- // for an individual read to complete.
- //
- // A value of zero means no timeout.
- ReadTimeout time.Duration
-
- // WriteTimeout is the maximum time a request attempt will
- // wait for an individual write to complete.
- //
- // A value of zero means no timeout.
- WriteTimeout time.Duration
-
- // RequestTimeout is the maximum time a request attempt can
- // take before operations return a timeout error.
- //
- // This includes connection time, any redirects, and reading
- // the response body. The timer remains running after the request
- // is made so it can interrupt reading of the response data.
- //
- // A Timeout of zero means no timeout.
- RequestTimeout time.Duration
-
- // AttemptStrategy is the attempt strategy used for requests.
- aws.AttemptStrategy
-
- // Reserve the right of using private data.
- private byte
-
- // client used for requests
- client *http.Client
-}
-
-// The Bucket type encapsulates operations with an S3 bucket.
-type Bucket struct {
- *S3
- Name string
-}
-
-// The Owner type represents the owner of the object in an S3 bucket.
-type Owner struct {
- ID string
- DisplayName string
-}
-
-// Fold options into an Options struct
-//
-type Options struct {
- SSE bool
- Meta map[string][]string
- ContentEncoding string
- CacheControl string
- RedirectLocation string
- ContentMD5 string
- // What else?
- // Content-Disposition string
- //// The following become headers so they are []strings rather than strings... I think
- // x-amz-storage-class []string
-}
-
-type CopyOptions struct {
- Options
- MetadataDirective string
- ContentType string
-}
-
-// CopyObjectResult is the output from a Copy request
-type CopyObjectResult struct {
- ETag string
- LastModified string
-}
-
-// DefaultAttemptStrategy is the default AttemptStrategy used by S3 objects created by New.
-var DefaultAttemptStrategy = aws.AttemptStrategy{
- Min: 5,
- Total: 5 * time.Second,
- Delay: 200 * time.Millisecond,
-}
-
-// New creates a new S3. Optional client argument allows for custom http.clients to be used.
-func New(auth aws.Auth, region aws.Region, client ...*http.Client) *S3 {
-
- var httpclient *http.Client
-
- if len(client) > 0 {
- httpclient = client[0]
- }
-
- return &S3{Auth: auth, Region: region, AttemptStrategy: DefaultAttemptStrategy, client: httpclient}
-}
-
-// Bucket returns a Bucket with the given name.
-func (s3 *S3) Bucket(name string) *Bucket {
- if s3.Region.S3BucketEndpoint != "" || s3.Region.S3LowercaseBucket {
- name = strings.ToLower(name)
- }
- return &Bucket{s3, name}
-}
-
-var createBucketConfiguration = `<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
- <LocationConstraint>%s</LocationConstraint>
-</CreateBucketConfiguration>`
-
-// locationConstraint returns an io.Reader specifying a LocationConstraint if
-// required for the region.
-//
-// See http://goo.gl/bh9Kq for details.
-func (s3 *S3) locationConstraint() io.Reader {
- constraint := ""
- if s3.Region.S3LocationConstraint {
- constraint = fmt.Sprintf(createBucketConfiguration, s3.Region.Name)
- }
- return strings.NewReader(constraint)
-}
-
-type ACL string
-
-const (
- Private = ACL("private")
- PublicRead = ACL("public-read")
- PublicReadWrite = ACL("public-read-write")
- AuthenticatedRead = ACL("authenticated-read")
- BucketOwnerRead = ACL("bucket-owner-read")
- BucketOwnerFull = ACL("bucket-owner-full-control")
-)
-
-// PutBucket creates a new bucket.
-//
-// See http://goo.gl/ndjnR for details.
-func (b *Bucket) PutBucket(perm ACL) error {
- headers := map[string][]string{
- "x-amz-acl": {string(perm)},
- }
- req := &request{
- method: "PUT",
- bucket: b.Name,
- path: "/",
- headers: headers,
- payload: b.locationConstraint(),
- }
- return b.S3.query(req, nil)
-}
-
-// DelBucket removes an existing S3 bucket. All objects in the bucket must
-// be removed before the bucket itself can be removed.
-//
-// See http://goo.gl/GoBrY for details.
-func (b *Bucket) DelBucket() (err error) {
- req := &request{
- method: "DELETE",
- bucket: b.Name,
- path: "/",
- }
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- err = b.S3.query(req, nil)
- if !shouldRetry(err) {
- break
- }
- }
- return err
-}
-
-// Get retrieves an object from an S3 bucket.
-//
-// See http://goo.gl/isCO7 for details.
-func (b *Bucket) Get(path string) (data []byte, err error) {
- body, err := b.GetReader(path)
- defer func() {
- if body != nil {
- body.Close()
- }
- }()
- if err != nil {
- return nil, err
- }
- data, err = ioutil.ReadAll(body)
- return data, err
-}
-
-// GetReader retrieves an object from an S3 bucket,
-// returning the body of the HTTP response.
-// It is the caller's responsibility to call Close on rc when
-// finished reading.
-func (b *Bucket) GetReader(path string) (rc io.ReadCloser, err error) {
- resp, err := b.GetResponse(path)
- if resp != nil {
- return resp.Body, err
- }
- return nil, err
-}
-
-// GetResponse retrieves an object from an S3 bucket,
-// returning the HTTP response.
-// It is the caller's responsibility to call Close on rc when
-// finished reading
-func (b *Bucket) GetResponse(path string) (resp *http.Response, err error) {
- return b.GetResponseWithHeaders(path, make(http.Header))
-}
-
-// GetReaderWithHeaders retrieves an object from an S3 bucket
-// Accepts custom headers to be sent as the second parameter
-// returning the body of the HTTP response.
-// It is the caller's responsibility to call Close on rc when
-// finished reading
-func (b *Bucket) GetResponseWithHeaders(path string, headers map[string][]string) (resp *http.Response, err error) {
- req := &request{
- bucket: b.Name,
- path: path,
- headers: headers,
- }
- err = b.S3.prepare(req)
- if err != nil {
- return nil, err
- }
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- resp, err := b.S3.run(req, nil)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err != nil {
- return nil, err
- }
- return resp, nil
- }
- panic("unreachable")
-}
-
-// Exists checks whether or not an object exists on an S3 bucket using a HEAD request.
-func (b *Bucket) Exists(path string) (exists bool, err error) {
- req := &request{
- method: "HEAD",
- bucket: b.Name,
- path: path,
- }
- err = b.S3.prepare(req)
- if err != nil {
- return
- }
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- resp, err := b.S3.run(req, nil)
-
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
-
- if err != nil {
- // We can treat a 403 or 404 as non existance
- if e, ok := err.(*Error); ok && (e.StatusCode == 403 || e.StatusCode == 404) {
- return false, nil
- }
- return false, err
- }
-
- if resp.StatusCode/100 == 2 {
- exists = true
- }
- return exists, err
- }
- return false, fmt.Errorf("S3 Currently Unreachable")
-}
-
-// Head HEADs an object in the S3 bucket, returns the response with
-// no body see http://bit.ly/17K1ylI
-func (b *Bucket) Head(path string, headers map[string][]string) (*http.Response, error) {
- req := &request{
- method: "HEAD",
- bucket: b.Name,
- path: path,
- headers: headers,
- }
- err := b.S3.prepare(req)
- if err != nil {
- return nil, err
- }
-
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- resp, err := b.S3.run(req, nil)
- if shouldRetry(err) && attempt.HasNext() {
- continue
- }
- if err != nil {
- return nil, err
- }
- return resp, err
- }
- return nil, fmt.Errorf("S3 Currently Unreachable")
-}
-
-// Put inserts an object into the S3 bucket.
-//
-// See http://goo.gl/FEBPD for details.
-func (b *Bucket) Put(path string, data []byte, contType string, perm ACL, options Options) error {
- body := bytes.NewBuffer(data)
- return b.PutReader(path, body, int64(len(data)), contType, perm, options)
-}
-
-// PutCopy puts a copy of an object given by the key path into bucket b using b.Path as the target key
-func (b *Bucket) PutCopy(path string, perm ACL, options CopyOptions, source string) (*CopyObjectResult, error) {
- headers := map[string][]string{
- "x-amz-acl": {string(perm)},
- "x-amz-copy-source": {source},
- }
- options.addHeaders(headers)
- req := &request{
- method: "PUT",
- bucket: b.Name,
- path: path,
- headers: headers,
- }
- resp := &CopyObjectResult{}
- err := b.S3.query(req, resp)
- if err != nil {
- return resp, err
- }
- return resp, nil
-}
-
-/*
-PutHeader - like Put, inserts an object into the S3 bucket.
-Instead of Content-Type string, pass in custom headers to override defaults.
-*/
-func (b *Bucket) PutHeader(path string, data []byte, customHeaders map[string][]string, perm ACL) error {
- body := bytes.NewBuffer(data)
- return b.PutReaderHeader(path, body, int64(len(data)), customHeaders, perm)
-}
-
-// PutReader inserts an object into the S3 bucket by consuming data
-// from r until EOF.
-func (b *Bucket) PutReader(path string, r io.Reader, length int64, contType string, perm ACL, options Options) error {
- headers := map[string][]string{
- "Content-Length": {strconv.FormatInt(length, 10)},
- "Content-Type": {contType},
- "x-amz-acl": {string(perm)},
- }
- options.addHeaders(headers)
- req := &request{
- method: "PUT",
- bucket: b.Name,
- path: path,
- headers: headers,
- payload: r,
- }
- return b.S3.query(req, nil)
-}
-
-/*
-PutReaderHeader - like PutReader, inserts an object into S3 from a reader.
-Instead of Content-Type string, pass in custom headers to override defaults.
-*/
-func (b *Bucket) PutReaderHeader(path string, r io.Reader, length int64, customHeaders map[string][]string, perm ACL) error {
- // Default headers
- headers := map[string][]string{
- "Content-Length": {strconv.FormatInt(length, 10)},
- "Content-Type": {"application/text"},
- "x-amz-acl": {string(perm)},
- }
-
- // Override with custom headers
- for key, value := range customHeaders {
- headers[key] = value
- }
-
- req := &request{
- method: "PUT",
- bucket: b.Name,
- path: path,
- headers: headers,
- payload: r,
- }
- return b.S3.query(req, nil)
-}
-
-// addHeaders adds o's specified fields to headers
-func (o Options) addHeaders(headers map[string][]string) {
- if o.SSE {
- headers["x-amz-server-side-encryption"] = []string{"AES256"}
- }
- if len(o.ContentEncoding) != 0 {
- headers["Content-Encoding"] = []string{o.ContentEncoding}
- }
- if len(o.CacheControl) != 0 {
- headers["Cache-Control"] = []string{o.CacheControl}
- }
- if len(o.ContentMD5) != 0 {
- headers["Content-MD5"] = []string{o.ContentMD5}
- }
- if len(o.RedirectLocation) != 0 {
- headers["x-amz-website-redirect-location"] = []string{o.RedirectLocation}
- }
- for k, v := range o.Meta {
- headers["x-amz-meta-"+k] = v
- }
-}
-
-// addHeaders adds o's specified fields to headers
-func (o CopyOptions) addHeaders(headers map[string][]string) {
- o.Options.addHeaders(headers)
- if len(o.MetadataDirective) != 0 {
- headers["x-amz-metadata-directive"] = []string{o.MetadataDirective}
- }
- if len(o.ContentType) != 0 {
- headers["Content-Type"] = []string{o.ContentType}
- }
-}
-
-func makeXmlBuffer(doc []byte) *bytes.Buffer {
- buf := new(bytes.Buffer)
- buf.WriteString(xml.Header)
- buf.Write(doc)
- return buf
-}
-
-type RoutingRule struct {
- ConditionKeyPrefixEquals string `xml:"Condition>KeyPrefixEquals"`
- RedirectReplaceKeyPrefixWith string `xml:"Redirect>ReplaceKeyPrefixWith,omitempty"`
- RedirectReplaceKeyWith string `xml:"Redirect>ReplaceKeyWith,omitempty"`
-}
-
-type WebsiteConfiguration struct {
- XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ WebsiteConfiguration"`
- IndexDocumentSuffix string `xml:"IndexDocument>Suffix"`
- ErrorDocumentKey string `xml:"ErrorDocument>Key"`
- RoutingRules *[]RoutingRule `xml:"RoutingRules>RoutingRule,omitempty"`
-}
-
-func (b *Bucket) PutBucketWebsite(configuration WebsiteConfiguration) error {
-
- doc, err := xml.Marshal(configuration)
- if err != nil {
- return err
- }
-
- buf := makeXmlBuffer(doc)
-
- return b.PutBucketSubresource("website", buf, int64(buf.Len()))
-}
-
-func (b *Bucket) PutBucketSubresource(subresource string, r io.Reader, length int64) error {
- headers := map[string][]string{
- "Content-Length": {strconv.FormatInt(length, 10)},
- }
- req := &request{
- path: "/",
- method: "PUT",
- bucket: b.Name,
- headers: headers,
- payload: r,
- params: url.Values{subresource: {""}},
- }
-
- return b.S3.query(req, nil)
-}
-
-// Del removes an object from the S3 bucket.
-//
-// See http://goo.gl/APeTt for details.
-func (b *Bucket) Del(path string) error {
- req := &request{
- method: "DELETE",
- bucket: b.Name,
- path: path,
- }
- return b.S3.query(req, nil)
-}
-
-type Delete struct {
- Quiet bool `xml:"Quiet,omitempty"`
- Objects []Object `xml:"Object"`
-}
-
-type Object struct {
- Key string `xml:"Key"`
- VersionId string `xml:"VersionId,omitempty"`
-}
-
-// DelMulti removes up to 1000 objects from the S3 bucket.
-//
-// See http://goo.gl/jx6cWK for details.
-func (b *Bucket) DelMulti(objects Delete) error {
- doc, err := xml.Marshal(objects)
- if err != nil {
- return err
- }
-
- buf := makeXmlBuffer(doc)
- digest := md5.New()
- size, err := digest.Write(buf.Bytes())
- if err != nil {
- return err
- }
-
- headers := map[string][]string{
- "Content-Length": {strconv.FormatInt(int64(size), 10)},
- "Content-MD5": {base64.StdEncoding.EncodeToString(digest.Sum(nil))},
- "Content-Type": {"text/xml"},
- }
- req := &request{
- path: "/",
- method: "POST",
- params: url.Values{"delete": {""}},
- bucket: b.Name,
- headers: headers,
- payload: buf,
- }
-
- return b.S3.query(req, nil)
-}
-
-// The ListResp type holds the results of a List bucket operation.
-type ListResp struct {
- Name string
- Prefix string
- Delimiter string
- Marker string
- NextMarker string
- MaxKeys int
-
- // IsTruncated is true if the results have been truncated because
- // there are more keys and prefixes than can fit in MaxKeys.
- // N.B. this is the opposite sense to that documented (incorrectly) in
- // http://goo.gl/YjQTc
- IsTruncated bool
- Contents []Key
- CommonPrefixes []string `xml:">Prefix"`
-}
-
-// The Key type represents an item stored in an S3 bucket.
-type Key struct {
- Key string
- LastModified string
- Size int64
- // ETag gives the hex-encoded MD5 sum of the contents,
- // surrounded with double-quotes.
- ETag string
- StorageClass string
- Owner Owner
-}
-
-// List returns information about objects in an S3 bucket.
-//
-// The prefix parameter limits the response to keys that begin with the
-// specified prefix.
-//
-// The delim parameter causes the response to group all of the keys that
-// share a common prefix up to the next delimiter in a single entry within
-// the CommonPrefixes field. You can use delimiters to separate a bucket
-// into different groupings of keys, similar to how folders would work.
-//
-// The marker parameter specifies the key to start with when listing objects
-// in a bucket. Amazon S3 lists objects in alphabetical order and
-// will return keys alphabetically greater than the marker.
-//
-// The max parameter specifies how many keys + common prefixes to return in
-// the response. The default is 1000.
-//
-// For example, given these keys in a bucket:
-//
-// index.html
-// index2.html
-// photos/2006/January/sample.jpg
-// photos/2006/February/sample2.jpg
-// photos/2006/February/sample3.jpg
-// photos/2006/February/sample4.jpg
-//
-// Listing this bucket with delimiter set to "/" would yield the
-// following result:
-//
-// &ListResp{
-// Name: "sample-bucket",
-// MaxKeys: 1000,
-// Delimiter: "/",
-// Contents: []Key{
-// {Key: "index.html", "index2.html"},
-// },
-// CommonPrefixes: []string{
-// "photos/",
-// },
-// }
-//
-// Listing the same bucket with delimiter set to "/" and prefix set to
-// "photos/2006/" would yield the following result:
-//
-// &ListResp{
-// Name: "sample-bucket",
-// MaxKeys: 1000,
-// Delimiter: "/",
-// Prefix: "photos/2006/",
-// CommonPrefixes: []string{
-// "photos/2006/February/",
-// "photos/2006/January/",
-// },
-// }
-//
-// See http://goo.gl/YjQTc for details.
-func (b *Bucket) List(prefix, delim, marker string, max int) (result *ListResp, err error) {
- params := map[string][]string{
- "prefix": {prefix},
- "delimiter": {delim},
- "marker": {marker},
- }
- if max != 0 {
- params["max-keys"] = []string{strconv.FormatInt(int64(max), 10)}
- }
- req := &request{
- bucket: b.Name,
- params: params,
- }
- result = &ListResp{}
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- err = b.S3.query(req, result)
- if !shouldRetry(err) {
- break
- }
- }
- if err != nil {
- return nil, err
- }
- return result, nil
-}
-
-// The VersionsResp type holds the results of a list bucket Versions operation.
-type VersionsResp struct {
- Name string
- Prefix string
- KeyMarker string
- VersionIdMarker string
- MaxKeys int
- Delimiter string
- IsTruncated bool
- Versions []Version
- CommonPrefixes []string `xml:">Prefix"`
-}
-
-// The Version type represents an object version stored in an S3 bucket.
-type Version struct {
- Key string
- VersionId string
- IsLatest bool
- LastModified string
- // ETag gives the hex-encoded MD5 sum of the contents,
- // surrounded with double-quotes.
- ETag string
- Size int64
- Owner Owner
- StorageClass string
-}
-
-func (b *Bucket) Versions(prefix, delim, keyMarker string, versionIdMarker string, max int) (result *VersionsResp, err error) {
- params := map[string][]string{
- "versions": {""},
- "prefix": {prefix},
- "delimiter": {delim},
- }
-
- if len(versionIdMarker) != 0 {
- params["version-id-marker"] = []string{versionIdMarker}
- }
- if len(keyMarker) != 0 {
- params["key-marker"] = []string{keyMarker}
- }
-
- if max != 0 {
- params["max-keys"] = []string{strconv.FormatInt(int64(max), 10)}
- }
- req := &request{
- bucket: b.Name,
- params: params,
- }
- result = &VersionsResp{}
- for attempt := b.S3.AttemptStrategy.Start(); attempt.Next(); {
- err = b.S3.query(req, result)
- if !shouldRetry(err) {
- break
- }
- }
- if err != nil {
- return nil, err
- }
- return result, nil
-}
-
-// Returns a mapping of all key names in this bucket to Key objects
-func (b *Bucket) GetBucketContents() (*map[string]Key, error) {
- bucket_contents := map[string]Key{}
- prefix := ""
- path_separator := ""
- marker := ""
- for {
- contents, err := b.List(prefix, path_separator, marker, 1000)
- if err != nil {
- return &bucket_contents, err
- }
- for _, key := range contents.Contents {
- bucket_contents[key.Key] = key
- }
- if contents.IsTruncated {
- marker = contents.NextMarker
- } else {
- break
- }
- }
-
- return &bucket_contents, nil
-}
-
-// URL returns a non-signed URL that allows retriving the
-// object at path. It only works if the object is publicly
-// readable (see SignedURL).
-func (b *Bucket) URL(path string) string {
- req := &request{
- bucket: b.Name,
- path: path,
- }
- err := b.S3.prepare(req)
- if err != nil {
- panic(err)
- }
- u, err := req.url()
- if err != nil {
- panic(err)
- }
- u.RawQuery = ""
- return u.String()
-}
-
-// SignedURL returns a signed URL that allows anyone holding the URL
-// to retrieve the object at path. The signature is valid until expires.
-func (b *Bucket) SignedURL(path string, expires time.Time) string {
- req := &request{
- bucket: b.Name,
- path: path,
- params: url.Values{"Expires": {strconv.FormatInt(expires.Unix(), 10)}},
- }
- err := b.S3.prepare(req)
- if err != nil {
- panic(err)
- }
- u, err := req.url()
- if err != nil {
- panic(err)
- }
- if b.S3.Auth.Token() != "" {
- return u.String() + "&x-amz-security-token=" + url.QueryEscape(req.headers["X-Amz-Security-Token"][0])
- } else {
- return u.String()
- }
-}
-
-// UploadSignedURL returns a signed URL that allows anyone holding the URL
-// to upload the object at path. The signature is valid until expires.
-// contenttype is a string like image/png
-// path is the resource name in s3 terminalogy like images/ali.png [obviously exclusing the bucket name itself]
-func (b *Bucket) UploadSignedURL(path, method, content_type string, expires time.Time) string {
- expire_date := expires.Unix()
- if method != "POST" {
- method = "PUT"
- }
- stringToSign := method + "\n\n" + content_type + "\n" + strconv.FormatInt(expire_date, 10) + "\n/" + b.Name + "/" + path
- fmt.Println("String to sign:\n", stringToSign)
- a := b.S3.Auth
- secretKey := a.SecretKey
- accessId := a.AccessKey
- mac := hmac.New(sha1.New, []byte(secretKey))
- mac.Write([]byte(stringToSign))
- macsum := mac.Sum(nil)
- signature := base64.StdEncoding.EncodeToString([]byte(macsum))
- signature = strings.TrimSpace(signature)
-
- signedurl, err := url.Parse("https://" + b.Name + ".s3.amazonaws.com/")
- if err != nil {
- log.Println("ERROR sining url for S3 upload", err)
- return ""
- }
- signedurl.Path += path
- params := url.Values{}
- params.Add("AWSAccessKeyId", accessId)
- params.Add("Expires", strconv.FormatInt(expire_date, 10))
- params.Add("Signature", signature)
- if a.Token() != "" {
- params.Add("token", a.Token())
- }
-
- signedurl.RawQuery = params.Encode()
- return signedurl.String()
-}
-
-// PostFormArgs returns the action and input fields needed to allow anonymous
-// uploads to a bucket within the expiration limit
-func (b *Bucket) PostFormArgs(path string, expires time.Time, redirect string) (action string, fields map[string]string) {
- conditions := make([]string, 0)
- fields = map[string]string{
- "AWSAccessKeyId": b.Auth.AccessKey,
- "key": path,
- }
-
- conditions = append(conditions, fmt.Sprintf("{\"key\": \"%s\"}", path))
- conditions = append(conditions, fmt.Sprintf("{\"bucket\": \"%s\"}", b.Name))
- if redirect != "" {
- conditions = append(conditions, fmt.Sprintf("{\"success_action_redirect\": \"%s\"}", redirect))
- fields["success_action_redirect"] = redirect
- }
-
- vExpiration := expires.Format("2006-01-02T15:04:05Z")
- vConditions := strings.Join(conditions, ",")
- policy := fmt.Sprintf("{\"expiration\": \"%s\", \"conditions\": [%s]}", vExpiration, vConditions)
- policy64 := base64.StdEncoding.EncodeToString([]byte(policy))
- fields["policy"] = policy64
-
- signer := hmac.New(sha1.New, []byte(b.Auth.SecretKey))
- signer.Write([]byte(policy64))
- fields["signature"] = base64.StdEncoding.EncodeToString(signer.Sum(nil))
-
- action = fmt.Sprintf("%s/%s/", b.S3.Region.S3Endpoint, b.Name)
- return
-}
-
-type request struct {
- method string
- bucket string
- path string
- signpath string
- params url.Values
- headers http.Header
- baseurl string
- payload io.Reader
- prepared bool
-}
-
-func (req *request) url() (*url.URL, error) {
- u, err := url.Parse(req.baseurl)
- if err != nil {
- return nil, fmt.Errorf("bad S3 endpoint URL %q: %v", req.baseurl, err)
- }
- u.RawQuery = req.params.Encode()
- u.Path = req.path
- return u, nil
-}
-
-// query prepares and runs the req request.
-// If resp is not nil, the XML data contained in the response
-// body will be unmarshalled on it.
-func (s3 *S3) query(req *request, resp interface{}) error {
- err := s3.prepare(req)
- if err == nil {
- var httpResponse *http.Response
- httpResponse, err = s3.run(req, resp)
- if resp == nil && httpResponse != nil {
- httpResponse.Body.Close()
- }
- }
- return err
-}
-
-// prepare sets up req to be delivered to S3.
-func (s3 *S3) prepare(req *request) error {
- var signpath = req.path
-
- if !req.prepared {
- req.prepared = true
- if req.method == "" {
- req.method = "GET"
- }
- // Copy so they can be mutated without affecting on retries.
- params := make(url.Values)
- headers := make(http.Header)
- for k, v := range req.params {
- params[k] = v
- }
- for k, v := range req.headers {
- headers[k] = v
- }
- req.params = params
- req.headers = headers
- if !strings.HasPrefix(req.path, "/") {
- req.path = "/" + req.path
- }
- signpath = req.path
- if req.bucket != "" {
- req.baseurl = s3.Region.S3BucketEndpoint
- if req.baseurl == "" {
- // Use the path method to address the bucket.
- req.baseurl = s3.Region.S3Endpoint
- req.path = "/" + req.bucket + req.path
- } else {
- // Just in case, prevent injection.
- if strings.IndexAny(req.bucket, "/:@") >= 0 {
- return fmt.Errorf("bad S3 bucket: %q", req.bucket)
- }
- req.baseurl = strings.Replace(req.baseurl, "${bucket}", req.bucket, -1)
- }
- signpath = "/" + req.bucket + signpath
- }
- }
-
- // Always sign again as it's not clear how far the
- // server has handled a previous attempt.
- u, err := url.Parse(req.baseurl)
- if err != nil {
- return fmt.Errorf("bad S3 endpoint URL %q: %v", req.baseurl, err)
- }
- reqSignpathSpaceFix := (&url.URL{Path: signpath}).String()
- req.headers["Host"] = []string{u.Host}
- req.headers["Date"] = []string{time.Now().In(time.UTC).Format(time.RFC1123)}
- if s3.Auth.Token() != "" {
- req.headers["X-Amz-Security-Token"] = []string{s3.Auth.Token()}
- }
- sign(s3.Auth, req.method, reqSignpathSpaceFix, req.params, req.headers)
- return nil
-}
-
-// run sends req and returns the http response from the server.
-// If resp is not nil, the XML data contained in the response
-// body will be unmarshalled on it.
-func (s3 *S3) run(req *request, resp interface{}) (*http.Response, error) {
- if debug {
- log.Printf("Running S3 request: %#v", req)
- }
-
- u, err := req.url()
- if err != nil {
- return nil, err
- }
-
- hreq := http.Request{
- URL: u,
- Method: req.method,
- ProtoMajor: 1,
- ProtoMinor: 1,
- Close: true,
- Header: req.headers,
- }
-
- if v, ok := req.headers["Content-Length"]; ok {
- hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64)
- delete(req.headers, "Content-Length")
- }
- if req.payload != nil {
- hreq.Body = ioutil.NopCloser(req.payload)
- }
-
- if s3.client == nil {
- s3.client = &http.Client{
- Transport: &http.Transport{
- Dial: func(netw, addr string) (c net.Conn, err error) {
- c, err = net.DialTimeout(netw, addr, s3.ConnectTimeout)
- if err != nil {
- return
- }
-
- var deadline time.Time
- if s3.RequestTimeout > 0 {
- deadline = time.Now().Add(s3.RequestTimeout)
- c.SetDeadline(deadline)
- }
-
- if s3.ReadTimeout > 0 || s3.WriteTimeout > 0 {
- c = &ioTimeoutConn{
- TCPConn: c.(*net.TCPConn),
- readTimeout: s3.ReadTimeout,
- writeTimeout: s3.WriteTimeout,
- requestDeadline: deadline,
- }
- }
- return
- },
- },
- }
- }
-
- hresp, err := s3.client.Do(&hreq)
- if err != nil {
- return nil, err
- }
- if debug {
- dump, _ := httputil.DumpResponse(hresp, true)
- log.Printf("} -> %s\n", dump)
- }
- if hresp.StatusCode != 200 && hresp.StatusCode != 204 && hresp.StatusCode != 206 {
- defer hresp.Body.Close()
- return nil, buildError(hresp)
- }
- if resp != nil {
- err = xml.NewDecoder(hresp.Body).Decode(resp)
- hresp.Body.Close()
- if debug {
- log.Printf("goamz.s3> decoded xml into %#v", resp)
- }
- }
- return hresp, err
-}
-
-// Error represents an error in an operation with S3.
-type Error struct {
- StatusCode int // HTTP status code (200, 403, ...)
- Code string // EC2 error code ("UnsupportedOperation", ...)
- Message string // The human-oriented error message
- BucketName string
- RequestId string
- HostId string
-}
-
-func (e *Error) Error() string {
- return e.Message
-}
-
-func buildError(r *http.Response) error {
- if debug {
- log.Printf("got error (status code %v)", r.StatusCode)
- data, err := ioutil.ReadAll(r.Body)
- if err != nil {
- log.Printf("\tread error: %v", err)
- } else {
- log.Printf("\tdata:\n%s\n\n", data)
- }
- r.Body = ioutil.NopCloser(bytes.NewBuffer(data))
- }
-
- err := Error{}
- // TODO return error if Unmarshal fails?
- xml.NewDecoder(r.Body).Decode(&err)
- r.Body.Close()
- err.StatusCode = r.StatusCode
- if err.Message == "" {
- err.Message = r.Status
- }
- if debug {
- log.Printf("err: %#v\n", err)
- }
- return &err
-}
-
-func shouldRetry(err error) bool {
- if err == nil {
- return false
- }
- if e, ok := err.(*url.Error); ok {
- // Transport returns this string if it detects a write on a connection which
- // has already had an error
- if e.Err.Error() == "http: can't write HTTP request on broken connection" {
- return true
- }
- err = e.Err
- }
-
- switch err {
- case io.ErrUnexpectedEOF, io.EOF:
- return true
- }
- switch e := err.(type) {
- case *net.DNSError:
- return true
- case *net.OpError:
- switch e.Op {
- case "read", "write", "WSARecv", "WSASend", "ConnectEx":
- return true
- }
- case *Error:
- switch e.Code {
- case "InternalError", "NoSuchUpload", "NoSuchBucket", "RequestTimeout":
- return true
- }
- // let's handle tls handshake timeout issues and similar temporary errors
- case net.Error:
- return e.Temporary()
- }
-
- return false
-}
-
-func hasCode(err error, code string) bool {
- s3err, ok := err.(*Error)
- return ok && s3err.Code == code
-}
-
-// ioTimeoutConn is a net.Conn which sets a deadline for each Read or Write operation
-type ioTimeoutConn struct {
- *net.TCPConn
- readTimeout time.Duration
- writeTimeout time.Duration
- requestDeadline time.Time
-}
-
-func (c *ioTimeoutConn) deadline(timeout time.Duration) time.Time {
- dl := time.Now().Add(timeout)
- if c.requestDeadline.IsZero() || dl.Before(c.requestDeadline) {
- return dl
- }
-
- return c.requestDeadline
-}
-
-func (c *ioTimeoutConn) Read(b []byte) (int, error) {
- if c.readTimeout > 0 {
- err := c.TCPConn.SetReadDeadline(c.deadline(c.readTimeout))
- if err != nil {
- return 0, err
- }
- }
- return c.TCPConn.Read(b)
-}
-
-func (c *ioTimeoutConn) Write(b []byte) (int, error) {
- if c.writeTimeout > 0 {
- err := c.TCPConn.SetWriteDeadline(c.deadline(c.writeTimeout))
- if err != nil {
- return 0, err
- }
- }
- return c.TCPConn.Write(b)
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3test/server.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3test/server.go
deleted file mode 100644
index 2016b5659..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3test/server.go
+++ /dev/null
@@ -1,633 +0,0 @@
-package s3test
-
-import (
- "bytes"
- "crypto/md5"
- "encoding/base64"
- "encoding/hex"
- "encoding/xml"
- "fmt"
- "github.com/goamz/goamz/s3"
- "io"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/url"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-)
-
-const debug = false
-
-type s3Error struct {
- statusCode int
- XMLName struct{} `xml:"Error"`
- Code string
- Message string
- BucketName string
- RequestId string
- HostId string
-}
-
-type action struct {
- srv *Server
- w http.ResponseWriter
- req *http.Request
- reqId string
-}
-
-// Config controls the internal behaviour of the Server. A nil config is the default
-// and behaves as if all configurations assume their default behaviour. Once passed
-// to NewServer, the configuration must not be modified.
-type Config struct {
- // Send409Conflict controls how the Server will respond to calls to PUT on a
- // previously existing bucket. The default is false, and corresponds to the
- // us-east-1 s3 enpoint. Setting this value to true emulates the behaviour of
- // all other regions.
- // http://docs.amazonwebservices.com/AmazonS3/latest/API/ErrorResponses.html
- Send409Conflict bool
-}
-
-func (c *Config) send409Conflict() bool {
- if c != nil {
- return c.Send409Conflict
- }
- return false
-}
-
-// Server is a fake S3 server for testing purposes.
-// All of the data for the server is kept in memory.
-type Server struct {
- url string
- reqId int
- listener net.Listener
- mu sync.Mutex
- buckets map[string]*bucket
- config *Config
-}
-
-type bucket struct {
- name string
- acl s3.ACL
- ctime time.Time
- objects map[string]*object
-}
-
-type object struct {
- name string
- mtime time.Time
- meta http.Header // metadata to return with requests.
- checksum []byte // also held as Content-MD5 in meta.
- data []byte
-}
-
-// A resource encapsulates the subject of an HTTP request.
-// The resource referred to may or may not exist
-// when the request is made.
-type resource interface {
- put(a *action) interface{}
- get(a *action) interface{}
- post(a *action) interface{}
- delete(a *action) interface{}
-}
-
-func NewServer(config *Config) (*Server, error) {
- l, err := net.Listen("tcp", "localhost:0")
- if err != nil {
- return nil, fmt.Errorf("cannot listen on localhost: %v", err)
- }
- srv := &Server{
- listener: l,
- url: "http://" + l.Addr().String(),
- buckets: make(map[string]*bucket),
- config: config,
- }
- go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- srv.serveHTTP(w, req)
- }))
- return srv, nil
-}
-
-// Quit closes down the server.
-func (srv *Server) Quit() {
- srv.listener.Close()
-}
-
-// URL returns a URL for the server.
-func (srv *Server) URL() string {
- return srv.url
-}
-
-func fatalf(code int, codeStr string, errf string, a ...interface{}) {
- panic(&s3Error{
- statusCode: code,
- Code: codeStr,
- Message: fmt.Sprintf(errf, a...),
- })
-}
-
-// serveHTTP serves the S3 protocol.
-func (srv *Server) serveHTTP(w http.ResponseWriter, req *http.Request) {
- // ignore error from ParseForm as it's usually spurious.
- req.ParseForm()
-
- srv.mu.Lock()
- defer srv.mu.Unlock()
-
- if debug {
- log.Printf("s3test %q %q", req.Method, req.URL)
- }
- a := &action{
- srv: srv,
- w: w,
- req: req,
- reqId: fmt.Sprintf("%09X", srv.reqId),
- }
- srv.reqId++
-
- var r resource
- defer func() {
- switch err := recover().(type) {
- case *s3Error:
- switch r := r.(type) {
- case objectResource:
- err.BucketName = r.bucket.name
- case bucketResource:
- err.BucketName = r.name
- }
- err.RequestId = a.reqId
- // TODO HostId
- w.Header().Set("Content-Type", `xml version="1.0" encoding="UTF-8"`)
- w.WriteHeader(err.statusCode)
- xmlMarshal(w, err)
- case nil:
- default:
- panic(err)
- }
- }()
-
- r = srv.resourceForURL(req.URL)
-
- var resp interface{}
- switch req.Method {
- case "PUT":
- resp = r.put(a)
- case "GET", "HEAD":
- resp = r.get(a)
- case "DELETE":
- resp = r.delete(a)
- case "POST":
- resp = r.post(a)
- default:
- fatalf(400, "MethodNotAllowed", "unknown http request method %q", req.Method)
- }
- if resp != nil && req.Method != "HEAD" {
- xmlMarshal(w, resp)
- }
-}
-
-// xmlMarshal is the same as xml.Marshal except that
-// it panics on error. The marshalling should not fail,
-// but we want to know if it does.
-func xmlMarshal(w io.Writer, x interface{}) {
- if err := xml.NewEncoder(w).Encode(x); err != nil {
- panic(fmt.Errorf("error marshalling %#v: %v", x, err))
- }
-}
-
-// In a fully implemented test server, each of these would have
-// its own resource type.
-var unimplementedBucketResourceNames = map[string]bool{
- "acl": true,
- "lifecycle": true,
- "policy": true,
- "location": true,
- "logging": true,
- "notification": true,
- "versions": true,
- "requestPayment": true,
- "versioning": true,
- "website": true,
- "uploads": true,
-}
-
-var unimplementedObjectResourceNames = map[string]bool{
- "uploadId": true,
- "acl": true,
- "torrent": true,
- "uploads": true,
-}
-
-var pathRegexp = regexp.MustCompile("/(([^/]+)(/(.*))?)?")
-
-// resourceForURL returns a resource object for the given URL.
-func (srv *Server) resourceForURL(u *url.URL) (r resource) {
- m := pathRegexp.FindStringSubmatch(u.Path)
- if m == nil {
- fatalf(404, "InvalidURI", "Couldn't parse the specified URI")
- }
- bucketName := m[2]
- objectName := m[4]
- if bucketName == "" {
- return nullResource{} // root
- }
- b := bucketResource{
- name: bucketName,
- bucket: srv.buckets[bucketName],
- }
- q := u.Query()
- if objectName == "" {
- for name := range q {
- if unimplementedBucketResourceNames[name] {
- return nullResource{}
- }
- }
- return b
-
- }
- if b.bucket == nil {
- fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
- }
- objr := objectResource{
- name: objectName,
- version: q.Get("versionId"),
- bucket: b.bucket,
- }
- for name := range q {
- if unimplementedObjectResourceNames[name] {
- return nullResource{}
- }
- }
- if obj := objr.bucket.objects[objr.name]; obj != nil {
- objr.object = obj
- }
- return objr
-}
-
-// nullResource has error stubs for all resource methods.
-type nullResource struct{}
-
-func notAllowed() interface{} {
- fatalf(400, "MethodNotAllowed", "The specified method is not allowed against this resource")
- return nil
-}
-
-func (nullResource) put(a *action) interface{} { return notAllowed() }
-func (nullResource) get(a *action) interface{} { return notAllowed() }
-func (nullResource) post(a *action) interface{} { return notAllowed() }
-func (nullResource) delete(a *action) interface{} { return notAllowed() }
-
-const timeFormat = "2006-01-02T15:04:05.000Z07:00"
-
-type bucketResource struct {
- name string
- bucket *bucket // non-nil if the bucket already exists.
-}
-
-// GET on a bucket lists the objects in the bucket.
-// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGET.html
-func (r bucketResource) get(a *action) interface{} {
- if r.bucket == nil {
- fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
- }
- delimiter := a.req.Form.Get("delimiter")
- marker := a.req.Form.Get("marker")
- maxKeys := -1
- if s := a.req.Form.Get("max-keys"); s != "" {
- i, err := strconv.Atoi(s)
- if err != nil || i < 0 {
- fatalf(400, "invalid value for max-keys: %q", s)
- }
- maxKeys = i
- }
- prefix := a.req.Form.Get("prefix")
- a.w.Header().Set("Content-Type", "application/xml")
-
- if a.req.Method == "HEAD" {
- return nil
- }
-
- var objs orderedObjects
-
- // first get all matching objects and arrange them in alphabetical order.
- for name, obj := range r.bucket.objects {
- if strings.HasPrefix(name, prefix) {
- objs = append(objs, obj)
- }
- }
- sort.Sort(objs)
-
- if maxKeys <= 0 {
- maxKeys = 1000
- }
- resp := &s3.ListResp{
- Name: r.bucket.name,
- Prefix: prefix,
- Delimiter: delimiter,
- Marker: marker,
- MaxKeys: maxKeys,
- }
-
- var prefixes []string
- for _, obj := range objs {
- if !strings.HasPrefix(obj.name, prefix) {
- continue
- }
- name := obj.name
- isPrefix := false
- if delimiter != "" {
- if i := strings.Index(obj.name[len(prefix):], delimiter); i >= 0 {
- name = obj.name[:len(prefix)+i+len(delimiter)]
- if prefixes != nil && prefixes[len(prefixes)-1] == name {
- continue
- }
- isPrefix = true
- }
- }
- if name <= marker {
- continue
- }
- if len(resp.Contents)+len(prefixes) >= maxKeys {
- resp.IsTruncated = true
- break
- }
- if isPrefix {
- prefixes = append(prefixes, name)
- } else {
- // Contents contains only keys not found in CommonPrefixes
- resp.Contents = append(resp.Contents, obj.s3Key())
- }
- }
- resp.CommonPrefixes = prefixes
- return resp
-}
-
-// orderedObjects holds a slice of objects that can be sorted
-// by name.
-type orderedObjects []*object
-
-func (s orderedObjects) Len() int {
- return len(s)
-}
-func (s orderedObjects) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-func (s orderedObjects) Less(i, j int) bool {
- return s[i].name < s[j].name
-}
-
-func (obj *object) s3Key() s3.Key {
- return s3.Key{
- Key: obj.name,
- LastModified: obj.mtime.Format(timeFormat),
- Size: int64(len(obj.data)),
- ETag: fmt.Sprintf(`"%x"`, obj.checksum),
- // TODO StorageClass
- // TODO Owner
- }
-}
-
-// DELETE on a bucket deletes the bucket if it's not empty.
-func (r bucketResource) delete(a *action) interface{} {
- b := r.bucket
- if b == nil {
- fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
- }
- if len(b.objects) > 0 {
- fatalf(400, "BucketNotEmpty", "The bucket you tried to delete is not empty")
- }
- delete(a.srv.buckets, b.name)
- return nil
-}
-
-// PUT on a bucket creates the bucket.
-// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html
-func (r bucketResource) put(a *action) interface{} {
- var created bool
- if r.bucket == nil {
- if !validBucketName(r.name) {
- fatalf(400, "InvalidBucketName", "The specified bucket is not valid")
- }
- if loc := locationConstraint(a); loc == "" {
- fatalf(400, "InvalidRequets", "The unspecified location constraint is incompatible for the region specific endpoint this request was sent to.")
- }
- // TODO validate acl
- r.bucket = &bucket{
- name: r.name,
- // TODO default acl
- objects: make(map[string]*object),
- }
- a.srv.buckets[r.name] = r.bucket
- created = true
- }
- if !created && a.srv.config.send409Conflict() {
- fatalf(409, "BucketAlreadyOwnedByYou", "Your previous request to create the named bucket succeeded and you already own it.")
- }
- r.bucket.acl = s3.ACL(a.req.Header.Get("x-amz-acl"))
- return nil
-}
-
-func (bucketResource) post(a *action) interface{} {
- fatalf(400, "Method", "bucket POST method not available")
- return nil
-}
-
-// validBucketName returns whether name is a valid bucket name.
-// Here are the rules, from:
-// http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/BucketRestrictions.html
-//
-// Can contain lowercase letters, numbers, periods (.), underscores (_),
-// and dashes (-). You can use uppercase letters for buckets only in the
-// US Standard region.
-//
-// Must start with a number or letter
-//
-// Must be between 3 and 255 characters long
-//
-// There's one extra rule (Must not be formatted as an IP address (e.g., 192.168.5.4)
-// but the real S3 server does not seem to check that rule, so we will not
-// check it either.
-//
-func validBucketName(name string) bool {
- if len(name) < 3 || len(name) > 255 {
- return false
- }
- r := name[0]
- if !(r >= '0' && r <= '9' || r >= 'a' && r <= 'z') {
- return false
- }
- for _, r := range name {
- switch {
- case r >= '0' && r <= '9':
- case r >= 'a' && r <= 'z':
- case r == '_' || r == '-':
- case r == '.':
- default:
- return false
- }
- }
- return true
-}
-
-var responseParams = map[string]bool{
- "content-type": true,
- "content-language": true,
- "expires": true,
- "cache-control": true,
- "content-disposition": true,
- "content-encoding": true,
-}
-
-type objectResource struct {
- name string
- version string
- bucket *bucket // always non-nil.
- object *object // may be nil.
-}
-
-// GET on an object gets the contents of the object.
-// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html
-func (objr objectResource) get(a *action) interface{} {
- obj := objr.object
- if obj == nil {
- fatalf(404, "NoSuchKey", "The specified key does not exist.")
- }
- h := a.w.Header()
- // add metadata
- for name, d := range obj.meta {
- h[name] = d
- }
- // override header values in response to request parameters.
- for name, vals := range a.req.Form {
- if strings.HasPrefix(name, "response-") {
- name = name[len("response-"):]
- if !responseParams[name] {
- continue
- }
- h.Set(name, vals[0])
- }
- }
- if r := a.req.Header.Get("Range"); r != "" {
- fatalf(400, "NotImplemented", "range unimplemented")
- }
- // TODO Last-Modified-Since
- // TODO If-Modified-Since
- // TODO If-Unmodified-Since
- // TODO If-Match
- // TODO If-None-Match
- // TODO Connection: close ??
- // TODO x-amz-request-id
- h.Set("Content-Length", fmt.Sprint(len(obj.data)))
- h.Set("ETag", hex.EncodeToString(obj.checksum))
- h.Set("Last-Modified", obj.mtime.Format(time.RFC1123))
- if a.req.Method == "HEAD" {
- return nil
- }
- // TODO avoid holding the lock when writing data.
- _, err := a.w.Write(obj.data)
- if err != nil {
- // we can't do much except just log the fact.
- log.Printf("error writing data: %v", err)
- }
- return nil
-}
-
-var metaHeaders = map[string]bool{
- "Content-MD5": true,
- "x-amz-acl": true,
- "Content-Type": true,
- "Content-Encoding": true,
- "Content-Disposition": true,
-}
-
-// PUT on an object creates the object.
-func (objr objectResource) put(a *action) interface{} {
- // TODO Cache-Control header
- // TODO Expires header
- // TODO x-amz-server-side-encryption
- // TODO x-amz-storage-class
-
- // TODO is this correct, or should we erase all previous metadata?
- obj := objr.object
- if obj == nil {
- obj = &object{
- name: objr.name,
- meta: make(http.Header),
- }
- }
-
- var expectHash []byte
- if c := a.req.Header.Get("Content-MD5"); c != "" {
- var err error
- expectHash, err = base64.StdEncoding.DecodeString(c)
- if err != nil || len(expectHash) != md5.Size {
- fatalf(400, "InvalidDigest", "The Content-MD5 you specified was invalid")
- }
- }
- sum := md5.New()
- // TODO avoid holding lock while reading data.
- data, err := ioutil.ReadAll(io.TeeReader(a.req.Body, sum))
- if err != nil {
- fatalf(400, "TODO", "read error")
- }
- gotHash := sum.Sum(nil)
- if expectHash != nil && bytes.Compare(gotHash, expectHash) != 0 {
- fatalf(400, "BadDigest", "The Content-MD5 you specified did not match what we received")
- }
- if a.req.ContentLength >= 0 && int64(len(data)) != a.req.ContentLength {
- fatalf(400, "IncompleteBody", "You did not provide the number of bytes specified by the Content-Length HTTP header")
- }
-
- // PUT request has been successful - save data and metadata
- for key, values := range a.req.Header {
- key = http.CanonicalHeaderKey(key)
- if metaHeaders[key] || strings.HasPrefix(key, "X-Amz-Meta-") {
- obj.meta[key] = values
- }
- }
- obj.data = data
- obj.checksum = gotHash
- obj.mtime = time.Now()
- objr.bucket.objects[objr.name] = obj
-
- h := a.w.Header()
- h.Set("ETag", fmt.Sprintf(`"%s"`, hex.EncodeToString(obj.checksum)))
-
- return nil
-}
-
-func (objr objectResource) delete(a *action) interface{} {
- delete(objr.bucket.objects, objr.name)
- return nil
-}
-
-func (objr objectResource) post(a *action) interface{} {
- fatalf(400, "MethodNotAllowed", "The specified method is not allowed against this resource")
- return nil
-}
-
-type CreateBucketConfiguration struct {
- LocationConstraint string
-}
-
-// locationConstraint parses the <CreateBucketConfiguration /> request body (if present).
-// If there is no body, an empty string will be returned.
-func locationConstraint(a *action) string {
- var body bytes.Buffer
- if _, err := io.Copy(&body, a.req.Body); err != nil {
- fatalf(400, "InvalidRequest", err.Error())
- }
- if body.Len() == 0 {
- return ""
- }
- var loc CreateBucketConfiguration
- if err := xml.NewDecoder(&body).Decode(&loc); err != nil {
- fatalf(400, "InvalidRequest", err.Error())
- }
- return loc.LocationConstraint
-}
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign.go
deleted file mode 100644
index 722d97d29..000000000
--- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package s3
-
-import (
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base64"
- "github.com/goamz/goamz/aws"
- "log"
- "sort"
- "strings"
-)
-
-var b64 = base64.StdEncoding
-
-// ----------------------------------------------------------------------------
-// S3 signing (http://goo.gl/G1LrK)
-
-var s3ParamsToSign = map[string]bool{
- "acl": true,
- "location": true,
- "logging": true,
- "notification": true,
- "partNumber": true,
- "policy": true,
- "requestPayment": true,
- "torrent": true,
- "uploadId": true,
- "uploads": true,
- "versionId": true,
- "versioning": true,
- "versions": true,
- "response-content-type": true,
- "response-content-language": true,
- "response-expires": true,
- "response-cache-control": true,
- "response-content-disposition": true,
- "response-content-encoding": true,
- "website": true,
- "delete": true,
-}
-
-type keySortableTupleList []keySortableTuple
-
-type keySortableTuple struct {
- Key string
- TupleString string
-}
-
-func (l keySortableTupleList) StringSlice() []string {
- slice := make([]string, len(l))
- for i, v := range l {
- slice[i] = v.TupleString
- }
- return slice
-}
-
-func (l keySortableTupleList) Len() int {
- return len(l)
-}
-
-func (l keySortableTupleList) Less(i, j int) bool {
- return l[i].Key < l[j].Key
-}
-
-func (l keySortableTupleList) Swap(i, j int) {
- l[i], l[j] = l[j], l[i]
-}
-
-func sign(auth aws.Auth, method, canonicalPath string, params, headers map[string][]string) {
- var md5, ctype, date, xamz string
- var xamzDate bool
- var sarray keySortableTupleList
- for k, v := range headers {
- k = strings.ToLower(k)
- switch k {
- case "content-md5":
- md5 = v[0]
- case "content-type":
- ctype = v[0]
- case "date":
- if !xamzDate {
- date = v[0]
- }
- default:
- if strings.HasPrefix(k, "x-amz-") {
- vall := strings.Join(v, ",")
- sarray = append(sarray, keySortableTuple{k, k + ":" + vall})
- if k == "x-amz-date" {
- xamzDate = true
- date = ""
- }
- }
- }
- }
- if len(sarray) > 0 {
- sort.Sort(sarray)
- xamz = strings.Join(sarray.StringSlice(), "\n") + "\n"
- }
-
- expires := false
- if v, ok := params["Expires"]; ok {
- // Query string request authentication alternative.
- expires = true
- date = v[0]
- params["AWSAccessKeyId"] = []string{auth.AccessKey}
- }
-
- sarray = sarray[0:0]
- for k, v := range params {
- if s3ParamsToSign[k] {
- for _, vi := range v {
- if vi == "" {
- sarray = append(sarray, keySortableTuple{k, k})
- } else {
- // "When signing you do not encode these values."
- sarray = append(sarray, keySortableTuple{k, k + "=" + vi})
- }
- }
- }
- }
- if len(sarray) > 0 {
- sort.Sort(sarray)
- canonicalPath = canonicalPath + "?" + strings.Join(sarray.StringSlice(), "&")
- }
-
- payload := method + "\n" + md5 + "\n" + ctype + "\n" + date + "\n" + xamz + canonicalPath
- hash := hmac.New(sha1.New, []byte(auth.SecretKey))
- hash.Write([]byte(payload))
- signature := make([]byte, b64.EncodedLen(hash.Size()))
- b64.Encode(signature, hash.Sum(nil))
-
- if expires {
- params["Signature"] = []string{string(signature)}
- } else {
- headers["Authorization"] = []string{"AWS " + auth.AccessKey + ":" + string(signature)}
- }
- if debug {
- log.Printf("Signature payload: %q", payload)
- log.Printf("Signature: %q", signature)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/AUTHORS b/Godeps/_workspace/src/github.com/golang/freetype/AUTHORS
deleted file mode 100644
index 7b70f7768..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/AUTHORS
+++ /dev/null
@@ -1,18 +0,0 @@
-# This is the official list of Freetype-Go authors for copyright purposes.
-# This file is distinct from the CONTRIBUTORS files.
-# See the latter for an explanation.
-#
-# Freetype-Go is derived from Freetype, which is written in C. The latter
-# is copyright 1996-2010 David Turner, Robert Wilhelm, and Werner Lemberg.
-
-# Names should be added to this file as
-# Name or Organization <email address>
-# The email address is not required for organizations.
-
-# Please keep the list sorted.
-
-Google Inc.
-Jeff R. Allen <jra@nella.org>
-Rémy Oudompheng <oudomphe@phare.normalesup.org>
-Roger Peppe <rogpeppe@gmail.com>
-Steven Edwards <steven@stephenwithav.com>
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/CONTRIBUTORS b/Godeps/_workspace/src/github.com/golang/freetype/CONTRIBUTORS
deleted file mode 100644
index 7494b12c3..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/CONTRIBUTORS
+++ /dev/null
@@ -1,36 +0,0 @@
-# This is the official list of people who can contribute
-# (and typically have contributed) code to the Freetype-Go repository.
-# The AUTHORS file lists the copyright holders; this file
-# lists people. For example, Google employees are listed here
-# but not in AUTHORS, because Google holds the copyright.
-#
-# The submission process automatically checks to make sure
-# that people submitting code are listed in this file (by email address).
-#
-# Names should be added to this file only after verifying that
-# the individual or the individual's organization has agreed to
-# the appropriate Contributor License Agreement, found here:
-#
-# http://code.google.com/legal/individual-cla-v1.0.html
-# http://code.google.com/legal/corporate-cla-v1.0.html
-#
-# The agreement for individuals can be filled out on the web.
-#
-# When adding J Random Contributor's name to this file,
-# either J's name or J's organization's name should be
-# added to the AUTHORS file, depending on whether the
-# individual or corporate CLA was used.
-
-# Names should be added to this file like so:
-# Name <email address>
-
-# Please keep the list sorted.
-
-Andrew Gerrand <adg@golang.org>
-Jeff R. Allen <jra@nella.org> <jeff.allen@gmail.com>
-Nigel Tao <nigeltao@golang.org>
-Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
-Rob Pike <r@golang.org>
-Roger Peppe <rogpeppe@gmail.com>
-Russ Cox <rsc@golang.org>
-Steven Edwards <steven@stephenwithav.com>
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/LICENSE b/Godeps/_workspace/src/github.com/golang/freetype/LICENSE
deleted file mode 100644
index e854ba5db..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/LICENSE
+++ /dev/null
@@ -1,12 +0,0 @@
-Use of the Freetype-Go software is subject to your choice of exactly one of
-the following two licenses:
- * The FreeType License, which is similar to the original BSD license with
- an advertising clause, or
- * The GNU General Public License (GPL), version 2 or later.
-
-The text of these licenses are available in the licenses/ftl.txt and the
-licenses/gpl.txt files respectively. They are also available at
-http://freetype.sourceforge.net/license.html
-
-The Luxi fonts in the testdata directory are licensed separately. See the
-testdata/COPYING file for details.
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/README b/Godeps/_workspace/src/github.com/golang/freetype/README
deleted file mode 100644
index 39b3d8250..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/README
+++ /dev/null
@@ -1,21 +0,0 @@
-The Freetype font rasterizer in the Go programming language.
-
-To download and install from source:
-$ go get github.com/golang/freetype
-
-It is an incomplete port:
- * It only supports TrueType fonts, and not Type 1 fonts nor bitmap fonts.
- * It only supports the Unicode encoding.
-
-There are also some implementation differences:
- * It uses a 26.6 fixed point co-ordinate system everywhere internally,
- as opposed to the original Freetype's mix of 26.6 (or 10.6 for 16-bit
- systems) in some places, and 24.8 in the "smooth" rasterizer.
-
-Freetype-Go is derived from Freetype, which is written in C. Freetype is
-copyright 1996-2010 David Turner, Robert Wilhelm, and Werner Lemberg.
-Freetype-Go is copyright The Freetype-Go Authors, who are listed in the
-AUTHORS file.
-
-Unless otherwise noted, the Freetype-Go source files are distributed
-under the BSD-style license found in the LICENSE file.
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/cmd/print-glyph-points/main.c b/Godeps/_workspace/src/github.com/golang/freetype/cmd/print-glyph-points/main.c
deleted file mode 100644
index 6e821e892..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/cmd/print-glyph-points/main.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-gcc main.c -I/usr/include/freetype2 -lfreetype && ./a.out 12 ../../testdata/luxisr.ttf with_hinting
-*/
-
-#include <stdio.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-void usage(char** argv) {
- fprintf(stderr, "usage: %s font_size font_file [with_hinting|sans_hinting]\n", argv[0]);
-}
-
-int main(int argc, char** argv) {
- FT_Error error;
- FT_Library library;
- FT_Face face;
- FT_Glyph_Metrics* m;
- FT_Outline* o;
- FT_Int major, minor, patch;
- int i, j, font_size, no_hinting;
-
- if (argc != 4) {
- usage(argv);
- return 1;
- }
- font_size = atoi(argv[1]);
- if (font_size <= 0) {
- fprintf(stderr, "invalid font_size\n");
- usage(argv);
- return 1;
- }
- if (!strcmp(argv[3], "with_hinting")) {
- no_hinting = 0;
- } else if (!strcmp(argv[3], "sans_hinting")) {
- no_hinting = 1;
- } else {
- fprintf(stderr, "neither \"with_hinting\" nor \"sans_hinting\"\n");
- usage(argv);
- return 1;
- };
- error = FT_Init_FreeType(&library);
- if (error) {
- fprintf(stderr, "FT_Init_FreeType: error #%d\n", error);
- return 1;
- }
- FT_Library_Version(library, &major, &minor, &patch);
- printf("freetype version %d.%d.%d\n", major, minor, patch);
- error = FT_New_Face(library, argv[2], 0, &face);
- if (error) {
- fprintf(stderr, "FT_New_Face: error #%d\n", error);
- return 1;
- }
- error = FT_Set_Char_Size(face, 0, font_size*64, 0, 0);
- if (error) {
- fprintf(stderr, "FT_Set_Char_Size: error #%d\n", error);
- return 1;
- }
- for (i = 0; i < face->num_glyphs; i++) {
- error = FT_Load_Glyph(face, i, no_hinting ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT);
- if (error) {
- fprintf(stderr, "FT_Load_Glyph: glyph %d: error #%d\n", i, error);
- return 1;
- }
- if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
- fprintf(stderr, "glyph format for glyph %d is not FT_GLYPH_FORMAT_OUTLINE\n", i);
- return 1;
- }
- m = &face->glyph->metrics;
- /* Print what Go calls the AdvanceWidth, and then: XMin, YMin, XMax, YMax. */
- printf("%ld %ld %ld %ld %ld;",
- m->horiAdvance,
- m->horiBearingX,
- m->horiBearingY - m->height,
- m->horiBearingX + m->width,
- m->horiBearingY);
- /* Print the glyph points. */
- o = &face->glyph->outline;
- for (j = 0; j < o->n_points; j++) {
- if (j != 0) {
- printf(", ");
- }
- printf("%ld %ld %d", o->points[j].x, o->points[j].y, o->tags[j] & 0x01);
- }
- printf("\n");
- }
- return 0;
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/drawer/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/drawer/main.go
deleted file mode 100644
index 4af981f9f..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/drawer/main.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2015 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "io/ioutil"
- "log"
- "math"
- "os"
-
- "github.com/golang/freetype/truetype"
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-var (
- dpi = flag.Float64("dpi", 72, "screen resolution in Dots Per Inch")
- fontfile = flag.String("fontfile", "../../testdata/luxisr.ttf", "filename of the ttf font")
- hinting = flag.String("hinting", "none", "none | full")
- size = flag.Float64("size", 12, "font size in points")
- spacing = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)")
- wonb = flag.Bool("whiteonblack", false, "white text on a black background")
-)
-
-const title = "Jabberwocky"
-
-var text = []string{
- "’Twas brillig, and the slithy toves",
- "Did gyre and gimble in the wabe;",
- "All mimsy were the borogoves,",
- "And the mome raths outgrabe.",
- "",
- "“Beware the Jabberwock, my son!",
- "The jaws that bite, the claws that catch!",
- "Beware the Jubjub bird, and shun",
- "The frumious Bandersnatch!â€",
- "",
- "He took his vorpal sword in hand:",
- "Long time the manxome foe he sought—",
- "So rested he by the Tumtum tree,",
- "And stood awhile in thought.",
- "",
- "And as in uffish thought he stood,",
- "The Jabberwock, with eyes of flame,",
- "Came whiffling through the tulgey wood,",
- "And burbled as it came!",
- "",
- "One, two! One, two! and through and through",
- "The vorpal blade went snicker-snack!",
- "He left it dead, and with its head",
- "He went galumphing back.",
- "",
- "“And hast thou slain the Jabberwock?",
- "Come to my arms, my beamish boy!",
- "O frabjous day! Callooh! Callay!â€",
- "He chortled in his joy.",
- "",
- "’Twas brillig, and the slithy toves",
- "Did gyre and gimble in the wabe;",
- "All mimsy were the borogoves,",
- "And the mome raths outgrabe.",
-}
-
-func main() {
- flag.Parse()
-
- // Read the font data.
- fontBytes, err := ioutil.ReadFile(*fontfile)
- if err != nil {
- log.Println(err)
- return
- }
- f, err := truetype.Parse(fontBytes)
- if err != nil {
- log.Println(err)
- return
- }
-
- // Draw the background and the guidelines.
- fg, bg := image.Black, image.White
- ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
- if *wonb {
- fg, bg = image.White, image.Black
- ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
- }
- const imgW, imgH = 640, 480
- rgba := image.NewRGBA(image.Rect(0, 0, imgW, imgH))
- draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
- for i := 0; i < 200; i++ {
- rgba.Set(10, 10+i, ruler)
- rgba.Set(10+i, 10, ruler)
- }
-
- // Draw the text.
- h := font.HintingNone
- switch *hinting {
- case "full":
- h = font.HintingFull
- }
- d := &font.Drawer{
- Dst: rgba,
- Src: fg,
- Face: truetype.NewFace(f, &truetype.Options{
- Size: *size,
- DPI: *dpi,
- Hinting: h,
- }),
- }
- y := 10 + int(math.Ceil(*size**dpi/72))
- dy := int(math.Ceil(*size * *spacing * *dpi / 72))
- d.Dot = fixed.Point26_6{
- X: (fixed.I(imgW) - d.MeasureString(title)) / 2,
- Y: fixed.I(y),
- }
- d.DrawString(title)
- y += dy
- for _, s := range text {
- d.Dot = fixed.P(10, y)
- d.DrawString(s)
- y += dy
- }
-
- // Save that RGBA image to disk.
- outFile, err := os.Create("out.png")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer outFile.Close()
- b := bufio.NewWriter(outFile)
- err = png.Encode(b, rgba)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- fmt.Println("Wrote out.png OK.")
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/freetype/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/freetype/main.go
deleted file mode 100644
index 21657a381..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/freetype/main.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "io/ioutil"
- "log"
- "os"
-
- "github.com/golang/freetype"
- "golang.org/x/image/font"
-)
-
-var (
- dpi = flag.Float64("dpi", 72, "screen resolution in Dots Per Inch")
- fontfile = flag.String("fontfile", "../../testdata/luxisr.ttf", "filename of the ttf font")
- hinting = flag.String("hinting", "none", "none | full")
- size = flag.Float64("size", 12, "font size in points")
- spacing = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)")
- wonb = flag.Bool("whiteonblack", false, "white text on a black background")
-)
-
-var text = []string{
- "’Twas brillig, and the slithy toves",
- "Did gyre and gimble in the wabe;",
- "All mimsy were the borogoves,",
- "And the mome raths outgrabe.",
- "",
- "“Beware the Jabberwock, my son!",
- "The jaws that bite, the claws that catch!",
- "Beware the Jubjub bird, and shun",
- "The frumious Bandersnatch!â€",
- "",
- "He took his vorpal sword in hand:",
- "Long time the manxome foe he sought—",
- "So rested he by the Tumtum tree,",
- "And stood awhile in thought.",
- "",
- "And as in uffish thought he stood,",
- "The Jabberwock, with eyes of flame,",
- "Came whiffling through the tulgey wood,",
- "And burbled as it came!",
- "",
- "One, two! One, two! and through and through",
- "The vorpal blade went snicker-snack!",
- "He left it dead, and with its head",
- "He went galumphing back.",
- "",
- "“And hast thou slain the Jabberwock?",
- "Come to my arms, my beamish boy!",
- "O frabjous day! Callooh! Callay!â€",
- "He chortled in his joy.",
- "",
- "’Twas brillig, and the slithy toves",
- "Did gyre and gimble in the wabe;",
- "All mimsy were the borogoves,",
- "And the mome raths outgrabe.",
-}
-
-func main() {
- flag.Parse()
-
- // Read the font data.
- fontBytes, err := ioutil.ReadFile(*fontfile)
- if err != nil {
- log.Println(err)
- return
- }
- f, err := freetype.ParseFont(fontBytes)
- if err != nil {
- log.Println(err)
- return
- }
-
- // Initialize the context.
- fg, bg := image.Black, image.White
- ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
- if *wonb {
- fg, bg = image.White, image.Black
- ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
- }
- rgba := image.NewRGBA(image.Rect(0, 0, 640, 480))
- draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
- c := freetype.NewContext()
- c.SetDPI(*dpi)
- c.SetFont(f)
- c.SetFontSize(*size)
- c.SetClip(rgba.Bounds())
- c.SetDst(rgba)
- c.SetSrc(fg)
- switch *hinting {
- default:
- c.SetHinting(font.HintingNone)
- case "full":
- c.SetHinting(font.HintingFull)
- }
-
- // Draw the guidelines.
- for i := 0; i < 200; i++ {
- rgba.Set(10, 10+i, ruler)
- rgba.Set(10+i, 10, ruler)
- }
-
- // Draw the text.
- pt := freetype.Pt(10, 10+int(c.PointToFixed(*size)>>6))
- for _, s := range text {
- _, err = c.DrawString(s, pt)
- if err != nil {
- log.Println(err)
- return
- }
- pt.Y += c.PointToFixed(*size * *spacing)
- }
-
- // Save that RGBA image to disk.
- outFile, err := os.Create("out.png")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer outFile.Close()
- b := bufio.NewWriter(outFile)
- err = png.Encode(b, rgba)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- fmt.Println("Wrote out.png OK.")
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/gamma/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/gamma/main.go
deleted file mode 100644
index 778697f4f..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/gamma/main.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-package main
-
-import (
- "bufio"
- "fmt"
- "image"
- "image/draw"
- "image/png"
- "log"
- "os"
-
- "github.com/golang/freetype/raster"
- "golang.org/x/image/math/fixed"
-)
-
-func p(x, y int) fixed.Point26_6 {
- return fixed.Point26_6{
- X: fixed.Int26_6(x * 64),
- Y: fixed.Int26_6(y * 64),
- }
-}
-
-func main() {
- // Draw a rounded corner that is one pixel wide.
- r := raster.NewRasterizer(50, 50)
- r.Start(p(5, 5))
- r.Add1(p(5, 25))
- r.Add2(p(5, 45), p(25, 45))
- r.Add1(p(45, 45))
- r.Add1(p(45, 44))
- r.Add1(p(26, 44))
- r.Add2(p(6, 44), p(6, 24))
- r.Add1(p(6, 5))
- r.Add1(p(5, 5))
-
- // Rasterize that curve multiple times at different gammas.
- const (
- w = 600
- h = 200
- )
- rgba := image.NewRGBA(image.Rect(0, 0, w, h))
- draw.Draw(rgba, image.Rect(0, 0, w, h/2), image.Black, image.ZP, draw.Src)
- draw.Draw(rgba, image.Rect(0, h/2, w, h), image.White, image.ZP, draw.Src)
- mask := image.NewAlpha(image.Rect(0, 0, 50, 50))
- painter := raster.NewAlphaSrcPainter(mask)
- gammas := []float64{1.0 / 10.0, 1.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0, 4.0 / 5.0, 1.0, 5.0 / 4.0, 3.0 / 2.0, 2.0, 3.0, 10.0}
- for i, g := range gammas {
- draw.Draw(mask, mask.Bounds(), image.Transparent, image.ZP, draw.Src)
- r.Rasterize(raster.NewGammaCorrectionPainter(painter, g))
- x, y := 50*i+25, 25
- draw.DrawMask(rgba, image.Rect(x, y, x+50, y+50), image.White, image.ZP, mask, image.ZP, draw.Over)
- y += 100
- draw.DrawMask(rgba, image.Rect(x, y, x+50, y+50), image.Black, image.ZP, mask, image.ZP, draw.Over)
- }
-
- // Save that RGBA image to disk.
- outFile, err := os.Create("out.png")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer outFile.Close()
- b := bufio.NewWriter(outFile)
- err = png.Encode(b, rgba)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- fmt.Println("Wrote out.png OK.")
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/raster/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/raster/main.go
deleted file mode 100644
index ae9c57f97..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/raster/main.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-package main
-
-import (
- "bufio"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "log"
- "os"
-
- "github.com/golang/freetype/raster"
- "golang.org/x/image/math/fixed"
-)
-
-type node struct {
- x, y, degree int
-}
-
-// These contours "outside" and "inside" are from the 'A' glyph from the Droid
-// Serif Regular font.
-
-var outside = []node{
- node{414, 489, 1},
- node{336, 274, 2},
- node{327, 250, 0},
- node{322, 226, 2},
- node{317, 203, 0},
- node{317, 186, 2},
- node{317, 134, 0},
- node{350, 110, 2},
- node{384, 86, 0},
- node{453, 86, 1},
- node{500, 86, 1},
- node{500, 0, 1},
- node{0, 0, 1},
- node{0, 86, 1},
- node{39, 86, 2},
- node{69, 86, 0},
- node{90, 92, 2},
- node{111, 99, 0},
- node{128, 117, 2},
- node{145, 135, 0},
- node{160, 166, 2},
- node{176, 197, 0},
- node{195, 246, 1},
- node{649, 1462, 1},
- node{809, 1462, 1},
- node{1272, 195, 2},
- node{1284, 163, 0},
- node{1296, 142, 2},
- node{1309, 121, 0},
- node{1326, 108, 2},
- node{1343, 96, 0},
- node{1365, 91, 2},
- node{1387, 86, 0},
- node{1417, 86, 1},
- node{1444, 86, 1},
- node{1444, 0, 1},
- node{881, 0, 1},
- node{881, 86, 1},
- node{928, 86, 2},
- node{1051, 86, 0},
- node{1051, 184, 2},
- node{1051, 201, 0},
- node{1046, 219, 2},
- node{1042, 237, 0},
- node{1034, 260, 1},
- node{952, 489, 1},
- node{414, 489, -1},
-}
-
-var inside = []node{
- node{686, 1274, 1},
- node{453, 592, 1},
- node{915, 592, 1},
- node{686, 1274, -1},
-}
-
-func p(n node) fixed.Point26_6 {
- x, y := 20+n.x/4, 380-n.y/4
- return fixed.Point26_6{
- X: fixed.Int26_6(x << 6),
- Y: fixed.Int26_6(y << 6),
- }
-}
-
-func contour(r *raster.Rasterizer, ns []node) {
- if len(ns) == 0 {
- return
- }
- i := 0
- r.Start(p(ns[i]))
- for {
- switch ns[i].degree {
- case -1:
- // -1 signifies end-of-contour.
- return
- case 1:
- i += 1
- r.Add1(p(ns[i]))
- case 2:
- i += 2
- r.Add2(p(ns[i-1]), p(ns[i]))
- default:
- panic("bad degree")
- }
- }
-}
-
-func showNodes(m *image.RGBA, ns []node) {
- for _, n := range ns {
- p := p(n)
- x, y := int(p.X)/64, int(p.Y)/64
- if !(image.Point{x, y}).In(m.Bounds()) {
- continue
- }
- var c color.Color
- switch n.degree {
- case 0:
- c = color.RGBA{0, 255, 255, 255}
- case 1:
- c = color.RGBA{255, 0, 0, 255}
- case 2:
- c = color.RGBA{255, 0, 0, 255}
- }
- if c != nil {
- m.Set(x, y, c)
- }
- }
-}
-
-func main() {
- // Rasterize the contours to a mask image.
- const (
- w = 400
- h = 400
- )
- r := raster.NewRasterizer(w, h)
- contour(r, outside)
- contour(r, inside)
- mask := image.NewAlpha(image.Rect(0, 0, w, h))
- p := raster.NewAlphaSrcPainter(mask)
- r.Rasterize(p)
-
- // Draw the mask image (in gray) onto an RGBA image.
- rgba := image.NewRGBA(image.Rect(0, 0, w, h))
- gray := image.NewUniform(color.Alpha{0x1f})
- draw.Draw(rgba, rgba.Bounds(), image.Black, image.ZP, draw.Src)
- draw.DrawMask(rgba, rgba.Bounds(), gray, image.ZP, mask, image.ZP, draw.Over)
- showNodes(rgba, outside)
- showNodes(rgba, inside)
-
- // Save that RGBA image to disk.
- outFile, err := os.Create("out.png")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer outFile.Close()
- b := bufio.NewWriter(outFile)
- err = png.Encode(b, rgba)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- fmt.Println("Wrote out.png OK.")
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/round/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/round/main.go
deleted file mode 100644
index 6c3012e62..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/round/main.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-// This program visualizes the quadratic approximation to the circle, used to
-// implement round joins when stroking paths. The approximation is used in the
-// stroking code for arcs between 0 and 45 degrees, but is visualized here
-// between 0 and 90 degrees. The discrepancy between the approximation and the
-// true circle is clearly visible at angles above 65 degrees.
-package main
-
-import (
- "bufio"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "log"
- "math"
- "os"
-
- "github.com/golang/freetype/raster"
- "golang.org/x/image/math/fixed"
-)
-
-// pDot returns the dot product p·q.
-func pDot(p, q fixed.Point26_6) fixed.Int52_12 {
- px, py := int64(p.X), int64(p.Y)
- qx, qy := int64(q.X), int64(q.Y)
- return fixed.Int52_12(px*qx + py*qy)
-}
-
-func main() {
- const (
- n = 17
- r = 64 * 80
- )
- s := fixed.Int26_6(r * math.Sqrt(2) / 2)
- t := fixed.Int26_6(r * math.Tan(math.Pi/8))
-
- m := image.NewRGBA(image.Rect(0, 0, 800, 600))
- draw.Draw(m, m.Bounds(), image.NewUniform(color.RGBA{63, 63, 63, 255}), image.ZP, draw.Src)
- mp := raster.NewRGBAPainter(m)
- mp.SetColor(image.Black)
- z := raster.NewRasterizer(800, 600)
-
- for i := 0; i < n; i++ {
- cx := fixed.Int26_6(6400 + 12800*(i%4))
- cy := fixed.Int26_6(640 + 8000*(i/4))
- c := fixed.Point26_6{X: cx, Y: cy}
- theta := math.Pi * (0.5 + 0.5*float64(i)/(n-1))
- dx := fixed.Int26_6(r * math.Cos(theta))
- dy := fixed.Int26_6(r * math.Sin(theta))
- d := fixed.Point26_6{X: dx, Y: dy}
- // Draw a quarter-circle approximated by two quadratic segments,
- // with each segment spanning 45 degrees.
- z.Start(c)
- z.Add1(c.Add(fixed.Point26_6{X: r, Y: 0}))
- z.Add2(c.Add(fixed.Point26_6{X: r, Y: t}), c.Add(fixed.Point26_6{X: s, Y: s}))
- z.Add2(c.Add(fixed.Point26_6{X: t, Y: r}), c.Add(fixed.Point26_6{X: 0, Y: r}))
- // Add another quadratic segment whose angle ranges between 0 and 90
- // degrees. For an explanation of the magic constants 128, 150, 181 and
- // 256, read the comments in the freetype/raster package.
- dot := 256 * pDot(d, fixed.Point26_6{X: 0, Y: r}) / (r * r)
- multiple := fixed.Int26_6(150-(150-128)*(dot-181)/(256-181)) >> 2
- z.Add2(c.Add(fixed.Point26_6{X: dx, Y: r + dy}.Mul(multiple)), c.Add(d))
- // Close the curve.
- z.Add1(c)
- }
- z.Rasterize(mp)
-
- for i := 0; i < n; i++ {
- cx := fixed.Int26_6(6400 + 12800*(i%4))
- cy := fixed.Int26_6(640 + 8000*(i/4))
- for j := 0; j < n; j++ {
- theta := math.Pi * float64(j) / (n - 1)
- dx := fixed.Int26_6(r * math.Cos(theta))
- dy := fixed.Int26_6(r * math.Sin(theta))
- m.Set(int((cx+dx)/64), int((cy+dy)/64), color.RGBA{255, 255, 0, 255})
- }
- }
-
- // Save that RGBA image to disk.
- outFile, err := os.Create("out.png")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer outFile.Close()
- b := bufio.NewWriter(outFile)
- err = png.Encode(b, m)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- fmt.Println("Wrote out.png OK.")
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/example/truetype/main.go b/Godeps/_workspace/src/github.com/golang/freetype/example/truetype/main.go
deleted file mode 100644
index 5fc72f771..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/example/truetype/main.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// +build ignore
-//
-// This build tag means that "go install github.com/golang/freetype/..."
-// doesn't install this example program. Use "go run main.go" to run it.
-
-package main
-
-import (
- "flag"
- "fmt"
- "io/ioutil"
- "log"
-
- "github.com/golang/freetype/truetype"
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-var fontfile = flag.String("fontfile", "../../testdata/luxisr.ttf", "filename of the ttf font")
-
-func printBounds(b fixed.Rectangle26_6) {
- fmt.Printf("Min.X:%d Min.Y:%d Max.X:%d Max.Y:%d\n", b.Min.X, b.Min.Y, b.Max.X, b.Max.Y)
-}
-
-func printGlyph(g *truetype.GlyphBuf) {
- printBounds(g.Bounds)
- fmt.Print("Points:\n---\n")
- e := 0
- for i, p := range g.Points {
- fmt.Printf("%4d, %4d", p.X, p.Y)
- if p.Flags&0x01 != 0 {
- fmt.Print(" on\n")
- } else {
- fmt.Print(" off\n")
- }
- if i+1 == int(g.Ends[e]) {
- fmt.Print("---\n")
- e++
- }
- }
-}
-
-func main() {
- flag.Parse()
- fmt.Printf("Loading fontfile %q\n", *fontfile)
- b, err := ioutil.ReadFile(*fontfile)
- if err != nil {
- log.Println(err)
- return
- }
- f, err := truetype.Parse(b)
- if err != nil {
- log.Println(err)
- return
- }
- fupe := fixed.Int26_6(f.FUnitsPerEm())
- printBounds(f.Bounds(fupe))
- fmt.Printf("FUnitsPerEm:%d\n\n", fupe)
-
- c0, c1 := 'A', 'V'
-
- i0 := f.Index(c0)
- hm := f.HMetric(fupe, i0)
- g := &truetype.GlyphBuf{}
- err = g.Load(f, fupe, i0, font.HintingNone)
- if err != nil {
- log.Println(err)
- return
- }
- fmt.Printf("'%c' glyph\n", c0)
- fmt.Printf("AdvanceWidth:%d LeftSideBearing:%d\n", hm.AdvanceWidth, hm.LeftSideBearing)
- printGlyph(g)
- i1 := f.Index(c1)
- fmt.Printf("\n'%c', '%c' Kern:%d\n", c0, c1, f.Kern(fupe, i0, i1))
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/freetype.go b/Godeps/_workspace/src/github.com/golang/freetype/freetype.go
deleted file mode 100644
index bec01f6b7..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/freetype.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// The freetype package provides a convenient API to draw text onto an image.
-// Use the freetype/raster and freetype/truetype packages for lower level
-// control over rasterization and TrueType parsing.
-package freetype
-
-import (
- "errors"
- "image"
- "image/draw"
-
- "github.com/golang/freetype/raster"
- "github.com/golang/freetype/truetype"
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-// These constants determine the size of the glyph cache. The cache is keyed
-// primarily by the glyph index modulo nGlyphs, and secondarily by sub-pixel
-// position for the mask image. Sub-pixel positions are quantized to
-// nXFractions possible values in both the x and y directions.
-const (
- nGlyphs = 256
- nXFractions = 4
- nYFractions = 1
-)
-
-// An entry in the glyph cache is keyed explicitly by the glyph index and
-// implicitly by the quantized x and y fractional offset. It maps to a mask
-// image and an offset.
-type cacheEntry struct {
- valid bool
- glyph truetype.Index
- advanceWidth fixed.Int26_6
- mask *image.Alpha
- offset image.Point
-}
-
-// ParseFont just calls the Parse function from the freetype/truetype package.
-// It is provided here so that code that imports this package doesn't need
-// to also include the freetype/truetype package.
-func ParseFont(b []byte) (*truetype.Font, error) {
- return truetype.Parse(b)
-}
-
-// Pt converts from a co-ordinate pair measured in pixels to a fixed.Point26_6
-// co-ordinate pair measured in fixed.Int26_6 units.
-func Pt(x, y int) fixed.Point26_6 {
- return fixed.Point26_6{
- X: fixed.Int26_6(x << 6),
- Y: fixed.Int26_6(y << 6),
- }
-}
-
-// A Context holds the state for drawing text in a given font and size.
-type Context struct {
- r *raster.Rasterizer
- f *truetype.Font
- glyphBuf truetype.GlyphBuf
- // clip is the clip rectangle for drawing.
- clip image.Rectangle
- // dst and src are the destination and source images for drawing.
- dst draw.Image
- src image.Image
- // fontSize and dpi are used to calculate scale. scale is the number of
- // 26.6 fixed point units in 1 em. hinting is the hinting policy.
- fontSize, dpi float64
- scale fixed.Int26_6
- hinting font.Hinting
- // cache is the glyph cache.
- cache [nGlyphs * nXFractions * nYFractions]cacheEntry
-}
-
-// PointToFixed converts the given number of points (as in "a 12 point font")
-// into a 26.6 fixed point number of pixels.
-func (c *Context) PointToFixed(x float64) fixed.Int26_6 {
- return fixed.Int26_6(x * float64(c.dpi) * (64.0 / 72.0))
-}
-
-// drawContour draws the given closed contour with the given offset.
-func (c *Context) drawContour(ps []truetype.Point, dx, dy fixed.Int26_6) {
- if len(ps) == 0 {
- return
- }
-
- // The low bit of each point's Flags value is whether the point is on the
- // curve. Truetype fonts only have quadratic Bézier curves, not cubics.
- // Thus, two consecutive off-curve points imply an on-curve point in the
- // middle of those two.
- //
- // See http://chanae.walon.org/pub/ttf/ttf_glyphs.htm for more details.
-
- // ps[0] is a truetype.Point measured in FUnits and positive Y going
- // upwards. start is the same thing measured in fixed point units and
- // positive Y going downwards, and offset by (dx, dy).
- start := fixed.Point26_6{
- X: dx + ps[0].X,
- Y: dy - ps[0].Y,
- }
- others := []truetype.Point(nil)
- if ps[0].Flags&0x01 != 0 {
- others = ps[1:]
- } else {
- last := fixed.Point26_6{
- X: dx + ps[len(ps)-1].X,
- Y: dy - ps[len(ps)-1].Y,
- }
- if ps[len(ps)-1].Flags&0x01 != 0 {
- start = last
- others = ps[:len(ps)-1]
- } else {
- start = fixed.Point26_6{
- X: (start.X + last.X) / 2,
- Y: (start.Y + last.Y) / 2,
- }
- others = ps
- }
- }
- c.r.Start(start)
- q0, on0 := start, true
- for _, p := range others {
- q := fixed.Point26_6{
- X: dx + p.X,
- Y: dy - p.Y,
- }
- on := p.Flags&0x01 != 0
- if on {
- if on0 {
- c.r.Add1(q)
- } else {
- c.r.Add2(q0, q)
- }
- } else {
- if on0 {
- // No-op.
- } else {
- mid := fixed.Point26_6{
- X: (q0.X + q.X) / 2,
- Y: (q0.Y + q.Y) / 2,
- }
- c.r.Add2(q0, mid)
- }
- }
- q0, on0 = q, on
- }
- // Close the curve.
- if on0 {
- c.r.Add1(start)
- } else {
- c.r.Add2(q0, start)
- }
-}
-
-// rasterize returns the advance width, glyph mask and integer-pixel offset
-// to render the given glyph at the given sub-pixel offsets.
-// The 26.6 fixed point arguments fx and fy must be in the range [0, 1).
-func (c *Context) rasterize(glyph truetype.Index, fx, fy fixed.Int26_6) (
- fixed.Int26_6, *image.Alpha, image.Point, error) {
-
- if err := c.glyphBuf.Load(c.f, c.scale, glyph, c.hinting); err != nil {
- return 0, nil, image.Point{}, err
- }
- // Calculate the integer-pixel bounds for the glyph.
- xmin := int(fx+c.glyphBuf.Bounds.Min.X) >> 6
- ymin := int(fy-c.glyphBuf.Bounds.Max.Y) >> 6
- xmax := int(fx+c.glyphBuf.Bounds.Max.X+0x3f) >> 6
- ymax := int(fy-c.glyphBuf.Bounds.Min.Y+0x3f) >> 6
- if xmin > xmax || ymin > ymax {
- return 0, nil, image.Point{}, errors.New("freetype: negative sized glyph")
- }
- // A TrueType's glyph's nodes can have negative co-ordinates, but the
- // rasterizer clips anything left of x=0 or above y=0. xmin and ymin are
- // the pixel offsets, based on the font's FUnit metrics, that let a
- // negative co-ordinate in TrueType space be non-negative in rasterizer
- // space. xmin and ymin are typically <= 0.
- fx -= fixed.Int26_6(xmin << 6)
- fy -= fixed.Int26_6(ymin << 6)
- // Rasterize the glyph's vectors.
- c.r.Clear()
- e0 := 0
- for _, e1 := range c.glyphBuf.Ends {
- c.drawContour(c.glyphBuf.Points[e0:e1], fx, fy)
- e0 = e1
- }
- a := image.NewAlpha(image.Rect(0, 0, xmax-xmin, ymax-ymin))
- c.r.Rasterize(raster.NewAlphaSrcPainter(a))
- return c.glyphBuf.AdvanceWidth, a, image.Point{xmin, ymin}, nil
-}
-
-// glyph returns the advance width, glyph mask and integer-pixel offset to
-// render the given glyph at the given sub-pixel point. It is a cache for the
-// rasterize method. Unlike rasterize, p's co-ordinates do not have to be in
-// the range [0, 1).
-func (c *Context) glyph(glyph truetype.Index, p fixed.Point26_6) (
- fixed.Int26_6, *image.Alpha, image.Point, error) {
-
- // Split p.X and p.Y into their integer and fractional parts.
- ix, fx := int(p.X>>6), p.X&0x3f
- iy, fy := int(p.Y>>6), p.Y&0x3f
- // Calculate the index t into the cache array.
- tg := int(glyph) % nGlyphs
- tx := int(fx) / (64 / nXFractions)
- ty := int(fy) / (64 / nYFractions)
- t := ((tg*nXFractions)+tx)*nYFractions + ty
- // Check for a cache hit.
- if e := c.cache[t]; e.valid && e.glyph == glyph {
- return e.advanceWidth, e.mask, e.offset.Add(image.Point{ix, iy}), nil
- }
- // Rasterize the glyph and put the result into the cache.
- advanceWidth, mask, offset, err := c.rasterize(glyph, fx, fy)
- if err != nil {
- return 0, nil, image.Point{}, err
- }
- c.cache[t] = cacheEntry{true, glyph, advanceWidth, mask, offset}
- return advanceWidth, mask, offset.Add(image.Point{ix, iy}), nil
-}
-
-// DrawString draws s at p and returns p advanced by the text extent. The text
-// is placed so that the left edge of the em square of the first character of s
-// and the baseline intersect at p. The majority of the affected pixels will be
-// above and to the right of the point, but some may be below or to the left.
-// For example, drawing a string that starts with a 'J' in an italic font may
-// affect pixels below and left of the point.
-//
-// p is a fixed.Point26_6 and can therefore represent sub-pixel positions.
-func (c *Context) DrawString(s string, p fixed.Point26_6) (fixed.Point26_6, error) {
- if c.f == nil {
- return fixed.Point26_6{}, errors.New("freetype: DrawText called with a nil font")
- }
- prev, hasPrev := truetype.Index(0), false
- for _, rune := range s {
- index := c.f.Index(rune)
- if hasPrev {
- kern := c.f.Kern(c.scale, prev, index)
- if c.hinting != font.HintingNone {
- kern = (kern + 32) &^ 63
- }
- p.X += kern
- }
- advanceWidth, mask, offset, err := c.glyph(index, p)
- if err != nil {
- return fixed.Point26_6{}, err
- }
- p.X += advanceWidth
- glyphRect := mask.Bounds().Add(offset)
- dr := c.clip.Intersect(glyphRect)
- if !dr.Empty() {
- mp := image.Point{0, dr.Min.Y - glyphRect.Min.Y}
- draw.DrawMask(c.dst, dr, c.src, image.ZP, mask, mp, draw.Over)
- }
- prev, hasPrev = index, true
- }
- return p, nil
-}
-
-// recalc recalculates scale and bounds values from the font size, screen
-// resolution and font metrics, and invalidates the glyph cache.
-func (c *Context) recalc() {
- c.scale = fixed.Int26_6(c.fontSize * c.dpi * (64.0 / 72.0))
- if c.f == nil {
- c.r.SetBounds(0, 0)
- } else {
- // Set the rasterizer's bounds to be big enough to handle the largest glyph.
- b := c.f.Bounds(c.scale)
- xmin := +int(b.Min.X) >> 6
- ymin := -int(b.Max.Y) >> 6
- xmax := +int(b.Max.X+63) >> 6
- ymax := -int(b.Min.Y-63) >> 6
- c.r.SetBounds(xmax-xmin, ymax-ymin)
- }
- for i := range c.cache {
- c.cache[i] = cacheEntry{}
- }
-}
-
-// SetDPI sets the screen resolution in dots per inch.
-func (c *Context) SetDPI(dpi float64) {
- if c.dpi == dpi {
- return
- }
- c.dpi = dpi
- c.recalc()
-}
-
-// SetFont sets the font used to draw text.
-func (c *Context) SetFont(f *truetype.Font) {
- if c.f == f {
- return
- }
- c.f = f
- c.recalc()
-}
-
-// SetFontSize sets the font size in points (as in "a 12 point font").
-func (c *Context) SetFontSize(fontSize float64) {
- if c.fontSize == fontSize {
- return
- }
- c.fontSize = fontSize
- c.recalc()
-}
-
-// SetHinting sets the hinting policy.
-func (c *Context) SetHinting(hinting font.Hinting) {
- c.hinting = hinting
- for i := range c.cache {
- c.cache[i] = cacheEntry{}
- }
-}
-
-// SetDst sets the destination image for draw operations.
-func (c *Context) SetDst(dst draw.Image) {
- c.dst = dst
-}
-
-// SetSrc sets the source image for draw operations. This is typically an
-// image.Uniform.
-func (c *Context) SetSrc(src image.Image) {
- c.src = src
-}
-
-// SetClip sets the clip rectangle for drawing.
-func (c *Context) SetClip(clip image.Rectangle) {
- c.clip = clip
-}
-
-// TODO(nigeltao): implement Context.SetGamma.
-
-// NewContext creates a new Context.
-func NewContext() *Context {
- return &Context{
- r: raster.NewRasterizer(0, 0),
- fontSize: 12,
- dpi: 72,
- scale: 12 << 6,
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/licenses/ftl.txt b/Godeps/_workspace/src/github.com/golang/freetype/licenses/ftl.txt
deleted file mode 100644
index bbaba33f4..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/licenses/ftl.txt
+++ /dev/null
@@ -1,169 +0,0 @@
- The FreeType Project LICENSE
- ----------------------------
-
- 2006-Jan-27
-
- Copyright 1996-2002, 2006 by
- David Turner, Robert Wilhelm, and Werner Lemberg
-
-
-
-Introduction
-============
-
- The FreeType Project is distributed in several archive packages;
- some of them may contain, in addition to the FreeType font engine,
- various tools and contributions which rely on, or relate to, the
- FreeType Project.
-
- This license applies to all files found in such packages, and
- which do not fall under their own explicit license. The license
- affects thus the FreeType font engine, the test programs,
- documentation and makefiles, at the very least.
-
- This license was inspired by the BSD, Artistic, and IJG
- (Independent JPEG Group) licenses, which all encourage inclusion
- and use of free software in commercial and freeware products
- alike. As a consequence, its main points are that:
-
- o We don't promise that this software works. However, we will be
- interested in any kind of bug reports. (`as is' distribution)
-
- o You can use this software for whatever you want, in parts or
- full form, without having to pay us. (`royalty-free' usage)
-
- o You may not pretend that you wrote this software. If you use
- it, or only parts of it, in a program, you must acknowledge
- somewhere in your documentation that you have used the
- FreeType code. (`credits')
-
- We specifically permit and encourage the inclusion of this
- software, with or without modifications, in commercial products.
- We disclaim all warranties covering The FreeType Project and
- assume no liability related to The FreeType Project.
-
-
- Finally, many people asked us for a preferred form for a
- credit/disclaimer to use in compliance with this license. We thus
- encourage you to use the following text:
-
- """
- Portions of this software are copyright © <year> The FreeType
- Project (www.freetype.org). All rights reserved.
- """
-
- Please replace <year> with the value from the FreeType version you
- actually use.
-
-
-Legal Terms
-===========
-
-0. Definitions
---------------
-
- Throughout this license, the terms `package', `FreeType Project',
- and `FreeType archive' refer to the set of files originally
- distributed by the authors (David Turner, Robert Wilhelm, and
- Werner Lemberg) as the `FreeType Project', be they named as alpha,
- beta or final release.
-
- `You' refers to the licensee, or person using the project, where
- `using' is a generic term including compiling the project's source
- code as well as linking it to form a `program' or `executable'.
- This program is referred to as `a program using the FreeType
- engine'.
-
- This license applies to all files distributed in the original
- FreeType Project, including all source code, binaries and
- documentation, unless otherwise stated in the file in its
- original, unmodified form as distributed in the original archive.
- If you are unsure whether or not a particular file is covered by
- this license, you must contact us to verify this.
-
- The FreeType Project is copyright (C) 1996-2000 by David Turner,
- Robert Wilhelm, and Werner Lemberg. All rights reserved except as
- specified below.
-
-1. No Warranty
---------------
-
- THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
- USE, OF THE FREETYPE PROJECT.
-
-2. Redistribution
------------------
-
- This license grants a worldwide, royalty-free, perpetual and
- irrevocable right and license to use, execute, perform, compile,
- display, copy, create derivative works of, distribute and
- sublicense the FreeType Project (in both source and object code
- forms) and derivative works thereof for any purpose; and to
- authorize others to exercise some or all of the rights granted
- herein, subject to the following conditions:
-
- o Redistribution of source code must retain this license file
- (`FTL.TXT') unaltered; any additions, deletions or changes to
- the original files must be clearly indicated in accompanying
- documentation. The copyright notices of the unaltered,
- original files must be preserved in all copies of source
- files.
-
- o Redistribution in binary form must provide a disclaimer that
- states that the software is based in part of the work of the
- FreeType Team, in the distribution documentation. We also
- encourage you to put an URL to the FreeType web page in your
- documentation, though this isn't mandatory.
-
- These conditions apply to any software derived from or based on
- the FreeType Project, not just the unmodified files. If you use
- our work, you must acknowledge us. However, no fee need be paid
- to us.
-
-3. Advertising
---------------
-
- Neither the FreeType authors and contributors nor you shall use
- the name of the other for commercial, advertising, or promotional
- purposes without specific prior written permission.
-
- We suggest, but do not require, that you use one or more of the
- following phrases to refer to this software in your documentation
- or advertising materials: `FreeType Project', `FreeType Engine',
- `FreeType library', or `FreeType Distribution'.
-
- As you have not signed this license, you are not required to
- accept it. However, as the FreeType Project is copyrighted
- material, only this license, or another one contracted with the
- authors, grants you the right to use, distribute, and modify it.
- Therefore, by using, distributing, or modifying the FreeType
- Project, you indicate that you understand and accept all the terms
- of this license.
-
-4. Contacts
------------
-
- There are two mailing lists related to FreeType:
-
- o freetype@nongnu.org
-
- Discusses general use and applications of FreeType, as well as
- future and wanted additions to the library and distribution.
- If you are looking for support, start in this list if you
- haven't found anything to help you in the documentation.
-
- o freetype-devel@nongnu.org
-
- Discusses bugs, as well as engine internals, design issues,
- specific licenses, porting, etc.
-
- Our home page can be found at
-
- http://www.freetype.org
-
-
---- end of FTL.TXT ---
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/licenses/gpl.txt b/Godeps/_workspace/src/github.com/golang/freetype/licenses/gpl.txt
deleted file mode 100644
index b2fe7b6af..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/licenses/gpl.txt
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/raster/geom.go b/Godeps/_workspace/src/github.com/golang/freetype/raster/geom.go
deleted file mode 100644
index f3696ea98..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/raster/geom.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package raster
-
-import (
- "fmt"
- "math"
-
- "golang.org/x/image/math/fixed"
-)
-
-// maxAbs returns the maximum of abs(a) and abs(b).
-func maxAbs(a, b fixed.Int26_6) fixed.Int26_6 {
- if a < 0 {
- a = -a
- }
- if b < 0 {
- b = -b
- }
- if a < b {
- return b
- }
- return a
-}
-
-// pNeg returns the vector -p, or equivalently p rotated by 180 degrees.
-func pNeg(p fixed.Point26_6) fixed.Point26_6 {
- return fixed.Point26_6{-p.X, -p.Y}
-}
-
-// pDot returns the dot product p·q.
-func pDot(p fixed.Point26_6, q fixed.Point26_6) fixed.Int52_12 {
- px, py := int64(p.X), int64(p.Y)
- qx, qy := int64(q.X), int64(q.Y)
- return fixed.Int52_12(px*qx + py*qy)
-}
-
-// pLen returns the length of the vector p.
-func pLen(p fixed.Point26_6) fixed.Int26_6 {
- // TODO(nigeltao): use fixed point math.
- x := float64(p.X)
- y := float64(p.Y)
- return fixed.Int26_6(math.Sqrt(x*x + y*y))
-}
-
-// pNorm returns the vector p normalized to the given length, or zero if p is
-// degenerate.
-func pNorm(p fixed.Point26_6, length fixed.Int26_6) fixed.Point26_6 {
- d := pLen(p)
- if d == 0 {
- return fixed.Point26_6{}
- }
- s, t := int64(length), int64(d)
- x := int64(p.X) * s / t
- y := int64(p.Y) * s / t
- return fixed.Point26_6{fixed.Int26_6(x), fixed.Int26_6(y)}
-}
-
-// pRot45CW returns the vector p rotated clockwise by 45 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot45CW is {1/√2, 1/√2}.
-func pRot45CW(p fixed.Point26_6) fixed.Point26_6 {
- // 181/256 is approximately 1/√2, or sin(π/4).
- px, py := int64(p.X), int64(p.Y)
- qx := (+px - py) * 181 / 256
- qy := (+px + py) * 181 / 256
- return fixed.Point26_6{fixed.Int26_6(qx), fixed.Int26_6(qy)}
-}
-
-// pRot90CW returns the vector p rotated clockwise by 90 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot90CW is {0, 1}.
-func pRot90CW(p fixed.Point26_6) fixed.Point26_6 {
- return fixed.Point26_6{-p.Y, p.X}
-}
-
-// pRot135CW returns the vector p rotated clockwise by 135 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot135CW is {-1/√2, 1/√2}.
-func pRot135CW(p fixed.Point26_6) fixed.Point26_6 {
- // 181/256 is approximately 1/√2, or sin(π/4).
- px, py := int64(p.X), int64(p.Y)
- qx := (-px - py) * 181 / 256
- qy := (+px - py) * 181 / 256
- return fixed.Point26_6{fixed.Int26_6(qx), fixed.Int26_6(qy)}
-}
-
-// pRot45CCW returns the vector p rotated counter-clockwise by 45 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot45CCW is {1/√2, -1/√2}.
-func pRot45CCW(p fixed.Point26_6) fixed.Point26_6 {
- // 181/256 is approximately 1/√2, or sin(π/4).
- px, py := int64(p.X), int64(p.Y)
- qx := (+px + py) * 181 / 256
- qy := (-px + py) * 181 / 256
- return fixed.Point26_6{fixed.Int26_6(qx), fixed.Int26_6(qy)}
-}
-
-// pRot90CCW returns the vector p rotated counter-clockwise by 90 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot90CCW is {0, -1}.
-func pRot90CCW(p fixed.Point26_6) fixed.Point26_6 {
- return fixed.Point26_6{p.Y, -p.X}
-}
-
-// pRot135CCW returns the vector p rotated counter-clockwise by 135 degrees.
-//
-// Note that the Y-axis grows downwards, so {1, 0}.Rot135CCW is {-1/√2, -1/√2}.
-func pRot135CCW(p fixed.Point26_6) fixed.Point26_6 {
- // 181/256 is approximately 1/√2, or sin(π/4).
- px, py := int64(p.X), int64(p.Y)
- qx := (-px + py) * 181 / 256
- qy := (-px - py) * 181 / 256
- return fixed.Point26_6{fixed.Int26_6(qx), fixed.Int26_6(qy)}
-}
-
-// An Adder accumulates points on a curve.
-type Adder interface {
- // Start starts a new curve at the given point.
- Start(a fixed.Point26_6)
- // Add1 adds a linear segment to the current curve.
- Add1(b fixed.Point26_6)
- // Add2 adds a quadratic segment to the current curve.
- Add2(b, c fixed.Point26_6)
- // Add3 adds a cubic segment to the current curve.
- Add3(b, c, d fixed.Point26_6)
-}
-
-// A Path is a sequence of curves, and a curve is a start point followed by a
-// sequence of linear, quadratic or cubic segments.
-type Path []fixed.Int26_6
-
-// String returns a human-readable representation of a Path.
-func (p Path) String() string {
- s := ""
- for i := 0; i < len(p); {
- if i != 0 {
- s += " "
- }
- switch p[i] {
- case 0:
- s += "S0" + fmt.Sprint([]fixed.Int26_6(p[i+1:i+3]))
- i += 4
- case 1:
- s += "A1" + fmt.Sprint([]fixed.Int26_6(p[i+1:i+3]))
- i += 4
- case 2:
- s += "A2" + fmt.Sprint([]fixed.Int26_6(p[i+1:i+5]))
- i += 6
- case 3:
- s += "A3" + fmt.Sprint([]fixed.Int26_6(p[i+1:i+7]))
- i += 8
- default:
- panic("freetype/raster: bad path")
- }
- }
- return s
-}
-
-// Clear cancels any previous calls to p.Start or p.AddXxx.
-func (p *Path) Clear() {
- *p = (*p)[:0]
-}
-
-// Start starts a new curve at the given point.
-func (p *Path) Start(a fixed.Point26_6) {
- *p = append(*p, 0, a.X, a.Y, 0)
-}
-
-// Add1 adds a linear segment to the current curve.
-func (p *Path) Add1(b fixed.Point26_6) {
- *p = append(*p, 1, b.X, b.Y, 1)
-}
-
-// Add2 adds a quadratic segment to the current curve.
-func (p *Path) Add2(b, c fixed.Point26_6) {
- *p = append(*p, 2, b.X, b.Y, c.X, c.Y, 2)
-}
-
-// Add3 adds a cubic segment to the current curve.
-func (p *Path) Add3(b, c, d fixed.Point26_6) {
- *p = append(*p, 3, b.X, b.Y, c.X, c.Y, d.X, d.Y, 3)
-}
-
-// AddPath adds the Path q to p.
-func (p *Path) AddPath(q Path) {
- *p = append(*p, q...)
-}
-
-// AddStroke adds a stroked Path.
-func (p *Path) AddStroke(q Path, width fixed.Int26_6, cr Capper, jr Joiner) {
- Stroke(p, q, width, cr, jr)
-}
-
-// firstPoint returns the first point in a non-empty Path.
-func (p Path) firstPoint() fixed.Point26_6 {
- return fixed.Point26_6{p[1], p[2]}
-}
-
-// lastPoint returns the last point in a non-empty Path.
-func (p Path) lastPoint() fixed.Point26_6 {
- return fixed.Point26_6{p[len(p)-3], p[len(p)-2]}
-}
-
-// addPathReversed adds q reversed to p.
-// For example, if q consists of a linear segment from A to B followed by a
-// quadratic segment from B to C to D, then the values of q looks like:
-// index: 01234567890123
-// value: 0AA01BB12CCDD2
-// So, when adding q backwards to p, we want to Add2(C, B) followed by Add1(A).
-func addPathReversed(p Adder, q Path) {
- if len(q) == 0 {
- return
- }
- i := len(q) - 1
- for {
- switch q[i] {
- case 0:
- return
- case 1:
- i -= 4
- p.Add1(
- fixed.Point26_6{q[i-2], q[i-1]},
- )
- case 2:
- i -= 6
- p.Add2(
- fixed.Point26_6{q[i+2], q[i+3]},
- fixed.Point26_6{q[i-2], q[i-1]},
- )
- case 3:
- i -= 8
- p.Add3(
- fixed.Point26_6{q[i+4], q[i+5]},
- fixed.Point26_6{q[i+2], q[i+3]},
- fixed.Point26_6{q[i-2], q[i-1]},
- )
- default:
- panic("freetype/raster: bad path")
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/raster/paint.go b/Godeps/_workspace/src/github.com/golang/freetype/raster/paint.go
deleted file mode 100644
index 185d36a8e..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/raster/paint.go
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package raster
-
-import (
- "image"
- "image/color"
- "image/draw"
- "math"
-)
-
-// A Span is a horizontal segment of pixels with constant alpha. X0 is an
-// inclusive bound and X1 is exclusive, the same as for slices. A fully opaque
-// Span has Alpha == 0xffff.
-type Span struct {
- Y, X0, X1 int
- Alpha uint32
-}
-
-// A Painter knows how to paint a batch of Spans. Rasterization may involve
-// Painting multiple batches, and done will be true for the final batch. The
-// Spans' Y values are monotonically increasing during a rasterization. Paint
-// may use all of ss as scratch space during the call.
-type Painter interface {
- Paint(ss []Span, done bool)
-}
-
-// The PainterFunc type adapts an ordinary function to the Painter interface.
-type PainterFunc func(ss []Span, done bool)
-
-// Paint just delegates the call to f.
-func (f PainterFunc) Paint(ss []Span, done bool) { f(ss, done) }
-
-// An AlphaOverPainter is a Painter that paints Spans onto a *image.Alpha using
-// the Over Porter-Duff composition operator.
-type AlphaOverPainter struct {
- Image *image.Alpha
-}
-
-// Paint satisfies the Painter interface.
-func (r AlphaOverPainter) Paint(ss []Span, done bool) {
- b := r.Image.Bounds()
- for _, s := range ss {
- if s.Y < b.Min.Y {
- continue
- }
- if s.Y >= b.Max.Y {
- return
- }
- if s.X0 < b.Min.X {
- s.X0 = b.Min.X
- }
- if s.X1 > b.Max.X {
- s.X1 = b.Max.X
- }
- if s.X0 >= s.X1 {
- continue
- }
- base := (s.Y-r.Image.Rect.Min.Y)*r.Image.Stride - r.Image.Rect.Min.X
- p := r.Image.Pix[base+s.X0 : base+s.X1]
- a := int(s.Alpha >> 8)
- for i, c := range p {
- v := int(c)
- p[i] = uint8((v*255 + (255-v)*a) / 255)
- }
- }
-}
-
-// NewAlphaOverPainter creates a new AlphaOverPainter for the given image.
-func NewAlphaOverPainter(m *image.Alpha) AlphaOverPainter {
- return AlphaOverPainter{m}
-}
-
-// An AlphaSrcPainter is a Painter that paints Spans onto a *image.Alpha using
-// the Src Porter-Duff composition operator.
-type AlphaSrcPainter struct {
- Image *image.Alpha
-}
-
-// Paint satisfies the Painter interface.
-func (r AlphaSrcPainter) Paint(ss []Span, done bool) {
- b := r.Image.Bounds()
- for _, s := range ss {
- if s.Y < b.Min.Y {
- continue
- }
- if s.Y >= b.Max.Y {
- return
- }
- if s.X0 < b.Min.X {
- s.X0 = b.Min.X
- }
- if s.X1 > b.Max.X {
- s.X1 = b.Max.X
- }
- if s.X0 >= s.X1 {
- continue
- }
- base := (s.Y-r.Image.Rect.Min.Y)*r.Image.Stride - r.Image.Rect.Min.X
- p := r.Image.Pix[base+s.X0 : base+s.X1]
- color := uint8(s.Alpha >> 8)
- for i := range p {
- p[i] = color
- }
- }
-}
-
-// NewAlphaSrcPainter creates a new AlphaSrcPainter for the given image.
-func NewAlphaSrcPainter(m *image.Alpha) AlphaSrcPainter {
- return AlphaSrcPainter{m}
-}
-
-// An RGBAPainter is a Painter that paints Spans onto a *image.RGBA.
-type RGBAPainter struct {
- // Image is the image to compose onto.
- Image *image.RGBA
- // Op is the Porter-Duff composition operator.
- Op draw.Op
- // cr, cg, cb and ca are the 16-bit color to paint the spans.
- cr, cg, cb, ca uint32
-}
-
-// Paint satisfies the Painter interface.
-func (r *RGBAPainter) Paint(ss []Span, done bool) {
- b := r.Image.Bounds()
- for _, s := range ss {
- if s.Y < b.Min.Y {
- continue
- }
- if s.Y >= b.Max.Y {
- return
- }
- if s.X0 < b.Min.X {
- s.X0 = b.Min.X
- }
- if s.X1 > b.Max.X {
- s.X1 = b.Max.X
- }
- if s.X0 >= s.X1 {
- continue
- }
- // This code mimics drawGlyphOver in $GOROOT/src/image/draw/draw.go.
- ma := s.Alpha
- const m = 1<<16 - 1
- i0 := (s.Y-r.Image.Rect.Min.Y)*r.Image.Stride + (s.X0-r.Image.Rect.Min.X)*4
- i1 := i0 + (s.X1-s.X0)*4
- if r.Op == draw.Over {
- for i := i0; i < i1; i += 4 {
- dr := uint32(r.Image.Pix[i+0])
- dg := uint32(r.Image.Pix[i+1])
- db := uint32(r.Image.Pix[i+2])
- da := uint32(r.Image.Pix[i+3])
- a := (m - (r.ca * ma / m)) * 0x101
- r.Image.Pix[i+0] = uint8((dr*a + r.cr*ma) / m >> 8)
- r.Image.Pix[i+1] = uint8((dg*a + r.cg*ma) / m >> 8)
- r.Image.Pix[i+2] = uint8((db*a + r.cb*ma) / m >> 8)
- r.Image.Pix[i+3] = uint8((da*a + r.ca*ma) / m >> 8)
- }
- } else {
- for i := i0; i < i1; i += 4 {
- r.Image.Pix[i+0] = uint8(r.cr * ma / m >> 8)
- r.Image.Pix[i+1] = uint8(r.cg * ma / m >> 8)
- r.Image.Pix[i+2] = uint8(r.cb * ma / m >> 8)
- r.Image.Pix[i+3] = uint8(r.ca * ma / m >> 8)
- }
- }
- }
-}
-
-// SetColor sets the color to paint the spans.
-func (r *RGBAPainter) SetColor(c color.Color) {
- r.cr, r.cg, r.cb, r.ca = c.RGBA()
-}
-
-// NewRGBAPainter creates a new RGBAPainter for the given image.
-func NewRGBAPainter(m *image.RGBA) *RGBAPainter {
- return &RGBAPainter{Image: m}
-}
-
-// A MonochromePainter wraps another Painter, quantizing each Span's alpha to
-// be either fully opaque or fully transparent.
-type MonochromePainter struct {
- Painter Painter
- y, x0, x1 int
-}
-
-// Paint delegates to the wrapped Painter after quantizing each Span's alpha
-// value and merging adjacent fully opaque Spans.
-func (m *MonochromePainter) Paint(ss []Span, done bool) {
- // We compact the ss slice, discarding any Spans whose alpha quantizes to zero.
- j := 0
- for _, s := range ss {
- if s.Alpha >= 0x8000 {
- if m.y == s.Y && m.x1 == s.X0 {
- m.x1 = s.X1
- } else {
- ss[j] = Span{m.y, m.x0, m.x1, 1<<32 - 1}
- j++
- m.y, m.x0, m.x1 = s.Y, s.X0, s.X1
- }
- }
- }
- if done {
- // Flush the accumulated Span.
- finalSpan := Span{m.y, m.x0, m.x1, 1<<32 - 1}
- if j < len(ss) {
- ss[j] = finalSpan
- j++
- m.Painter.Paint(ss[:j], true)
- } else if j == len(ss) {
- m.Painter.Paint(ss, false)
- if cap(ss) > 0 {
- ss = ss[:1]
- } else {
- ss = make([]Span, 1)
- }
- ss[0] = finalSpan
- m.Painter.Paint(ss, true)
- } else {
- panic("unreachable")
- }
- // Reset the accumulator, so that this Painter can be re-used.
- m.y, m.x0, m.x1 = 0, 0, 0
- } else {
- m.Painter.Paint(ss[:j], false)
- }
-}
-
-// NewMonochromePainter creates a new MonochromePainter that wraps the given
-// Painter.
-func NewMonochromePainter(p Painter) *MonochromePainter {
- return &MonochromePainter{Painter: p}
-}
-
-// A GammaCorrectionPainter wraps another Painter, performing gamma-correction
-// on each Span's alpha value.
-type GammaCorrectionPainter struct {
- // Painter is the wrapped Painter.
- Painter Painter
- // a is the precomputed alpha values for linear interpolation, with fully
- // opaque == 0xffff.
- a [256]uint16
- // gammaIsOne is whether gamma correction is a no-op.
- gammaIsOne bool
-}
-
-// Paint delegates to the wrapped Painter after performing gamma-correction on
-// each Span.
-func (g *GammaCorrectionPainter) Paint(ss []Span, done bool) {
- if !g.gammaIsOne {
- const n = 0x101
- for i, s := range ss {
- if s.Alpha == 0 || s.Alpha == 0xffff {
- continue
- }
- p, q := s.Alpha/n, s.Alpha%n
- // The resultant alpha is a linear interpolation of g.a[p] and g.a[p+1].
- a := uint32(g.a[p])*(n-q) + uint32(g.a[p+1])*q
- ss[i].Alpha = (a + n/2) / n
- }
- }
- g.Painter.Paint(ss, done)
-}
-
-// SetGamma sets the gamma value.
-func (g *GammaCorrectionPainter) SetGamma(gamma float64) {
- g.gammaIsOne = gamma == 1
- if g.gammaIsOne {
- return
- }
- for i := 0; i < 256; i++ {
- a := float64(i) / 0xff
- a = math.Pow(a, gamma)
- g.a[i] = uint16(0xffff * a)
- }
-}
-
-// NewGammaCorrectionPainter creates a new GammaCorrectionPainter that wraps
-// the given Painter.
-func NewGammaCorrectionPainter(p Painter, gamma float64) *GammaCorrectionPainter {
- g := &GammaCorrectionPainter{Painter: p}
- g.SetGamma(gamma)
- return g
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/raster/raster.go b/Godeps/_workspace/src/github.com/golang/freetype/raster/raster.go
deleted file mode 100644
index 995925e2a..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/raster/raster.go
+++ /dev/null
@@ -1,601 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// Package raster provides an anti-aliasing 2-D rasterizer.
-//
-// It is part of the larger Freetype suite of font-related packages, but the
-// raster package is not specific to font rasterization, and can be used
-// standalone without any other Freetype package.
-//
-// Rasterization is done by the same area/coverage accumulation algorithm as
-// the Freetype "smooth" module, and the Anti-Grain Geometry library. A
-// description of the area/coverage algorithm is at
-// http://projects.tuxee.net/cl-vectors/section-the-cl-aa-algorithm
-package raster
-
-import (
- "strconv"
-
- "golang.org/x/image/math/fixed"
-)
-
-// A cell is part of a linked list (for a given yi co-ordinate) of accumulated
-// area/coverage for the pixel at (xi, yi).
-type cell struct {
- xi int
- area, cover int
- next int
-}
-
-type Rasterizer struct {
- // If false, the default behavior is to use the even-odd winding fill
- // rule during Rasterize.
- UseNonZeroWinding bool
- // An offset (in pixels) to the painted spans.
- Dx, Dy int
-
- // The width of the Rasterizer. The height is implicit in len(cellIndex).
- width int
- // splitScaleN is the scaling factor used to determine how many times
- // to decompose a quadratic or cubic segment into a linear approximation.
- splitScale2, splitScale3 int
-
- // The current pen position.
- a fixed.Point26_6
- // The current cell and its area/coverage being accumulated.
- xi, yi int
- area, cover int
-
- // Saved cells.
- cell []cell
- // Linked list of cells, one per row.
- cellIndex []int
- // Buffers.
- cellBuf [256]cell
- cellIndexBuf [64]int
- spanBuf [64]Span
-}
-
-// findCell returns the index in r.cell for the cell corresponding to
-// (r.xi, r.yi). The cell is created if necessary.
-func (r *Rasterizer) findCell() int {
- if r.yi < 0 || r.yi >= len(r.cellIndex) {
- return -1
- }
- xi := r.xi
- if xi < 0 {
- xi = -1
- } else if xi > r.width {
- xi = r.width
- }
- i, prev := r.cellIndex[r.yi], -1
- for i != -1 && r.cell[i].xi <= xi {
- if r.cell[i].xi == xi {
- return i
- }
- i, prev = r.cell[i].next, i
- }
- c := len(r.cell)
- if c == cap(r.cell) {
- buf := make([]cell, c, 4*c)
- copy(buf, r.cell)
- r.cell = buf[0 : c+1]
- } else {
- r.cell = r.cell[0 : c+1]
- }
- r.cell[c] = cell{xi, 0, 0, i}
- if prev == -1 {
- r.cellIndex[r.yi] = c
- } else {
- r.cell[prev].next = c
- }
- return c
-}
-
-// saveCell saves any accumulated r.area/r.cover for (r.xi, r.yi).
-func (r *Rasterizer) saveCell() {
- if r.area != 0 || r.cover != 0 {
- i := r.findCell()
- if i != -1 {
- r.cell[i].area += r.area
- r.cell[i].cover += r.cover
- }
- r.area = 0
- r.cover = 0
- }
-}
-
-// setCell sets the (xi, yi) cell that r is accumulating area/coverage for.
-func (r *Rasterizer) setCell(xi, yi int) {
- if r.xi != xi || r.yi != yi {
- r.saveCell()
- r.xi, r.yi = xi, yi
- }
-}
-
-// scan accumulates area/coverage for the yi'th scanline, going from
-// x0 to x1 in the horizontal direction (in 26.6 fixed point co-ordinates)
-// and from y0f to y1f fractional vertical units within that scanline.
-func (r *Rasterizer) scan(yi int, x0, y0f, x1, y1f fixed.Int26_6) {
- // Break the 26.6 fixed point X co-ordinates into integral and fractional parts.
- x0i := int(x0) / 64
- x0f := x0 - fixed.Int26_6(64*x0i)
- x1i := int(x1) / 64
- x1f := x1 - fixed.Int26_6(64*x1i)
-
- // A perfectly horizontal scan.
- if y0f == y1f {
- r.setCell(x1i, yi)
- return
- }
- dx, dy := x1-x0, y1f-y0f
- // A single cell scan.
- if x0i == x1i {
- r.area += int((x0f + x1f) * dy)
- r.cover += int(dy)
- return
- }
- // There are at least two cells. Apart from the first and last cells,
- // all intermediate cells go through the full width of the cell,
- // or 64 units in 26.6 fixed point format.
- var (
- p, q, edge0, edge1 fixed.Int26_6
- xiDelta int
- )
- if dx > 0 {
- p, q = (64-x0f)*dy, dx
- edge0, edge1, xiDelta = 0, 64, 1
- } else {
- p, q = x0f*dy, -dx
- edge0, edge1, xiDelta = 64, 0, -1
- }
- yDelta, yRem := p/q, p%q
- if yRem < 0 {
- yDelta -= 1
- yRem += q
- }
- // Do the first cell.
- xi, y := x0i, y0f
- r.area += int((x0f + edge1) * yDelta)
- r.cover += int(yDelta)
- xi, y = xi+xiDelta, y+yDelta
- r.setCell(xi, yi)
- if xi != x1i {
- // Do all the intermediate cells.
- p = 64 * (y1f - y + yDelta)
- fullDelta, fullRem := p/q, p%q
- if fullRem < 0 {
- fullDelta -= 1
- fullRem += q
- }
- yRem -= q
- for xi != x1i {
- yDelta = fullDelta
- yRem += fullRem
- if yRem >= 0 {
- yDelta += 1
- yRem -= q
- }
- r.area += int(64 * yDelta)
- r.cover += int(yDelta)
- xi, y = xi+xiDelta, y+yDelta
- r.setCell(xi, yi)
- }
- }
- // Do the last cell.
- yDelta = y1f - y
- r.area += int((edge0 + x1f) * yDelta)
- r.cover += int(yDelta)
-}
-
-// Start starts a new curve at the given point.
-func (r *Rasterizer) Start(a fixed.Point26_6) {
- r.setCell(int(a.X/64), int(a.Y/64))
- r.a = a
-}
-
-// Add1 adds a linear segment to the current curve.
-func (r *Rasterizer) Add1(b fixed.Point26_6) {
- x0, y0 := r.a.X, r.a.Y
- x1, y1 := b.X, b.Y
- dx, dy := x1-x0, y1-y0
- // Break the 26.6 fixed point Y co-ordinates into integral and fractional
- // parts.
- y0i := int(y0) / 64
- y0f := y0 - fixed.Int26_6(64*y0i)
- y1i := int(y1) / 64
- y1f := y1 - fixed.Int26_6(64*y1i)
-
- if y0i == y1i {
- // There is only one scanline.
- r.scan(y0i, x0, y0f, x1, y1f)
-
- } else if dx == 0 {
- // This is a vertical line segment. We avoid calling r.scan and instead
- // manipulate r.area and r.cover directly.
- var (
- edge0, edge1 fixed.Int26_6
- yiDelta int
- )
- if dy > 0 {
- edge0, edge1, yiDelta = 0, 64, 1
- } else {
- edge0, edge1, yiDelta = 64, 0, -1
- }
- x0i, yi := int(x0)/64, y0i
- x0fTimes2 := (int(x0) - (64 * x0i)) * 2
- // Do the first pixel.
- dcover := int(edge1 - y0f)
- darea := int(x0fTimes2 * dcover)
- r.area += darea
- r.cover += dcover
- yi += yiDelta
- r.setCell(x0i, yi)
- // Do all the intermediate pixels.
- dcover = int(edge1 - edge0)
- darea = int(x0fTimes2 * dcover)
- for yi != y1i {
- r.area += darea
- r.cover += dcover
- yi += yiDelta
- r.setCell(x0i, yi)
- }
- // Do the last pixel.
- dcover = int(y1f - edge0)
- darea = int(x0fTimes2 * dcover)
- r.area += darea
- r.cover += dcover
-
- } else {
- // There are at least two scanlines. Apart from the first and last
- // scanlines, all intermediate scanlines go through the full height of
- // the row, or 64 units in 26.6 fixed point format.
- var (
- p, q, edge0, edge1 fixed.Int26_6
- yiDelta int
- )
- if dy > 0 {
- p, q = (64-y0f)*dx, dy
- edge0, edge1, yiDelta = 0, 64, 1
- } else {
- p, q = y0f*dx, -dy
- edge0, edge1, yiDelta = 64, 0, -1
- }
- xDelta, xRem := p/q, p%q
- if xRem < 0 {
- xDelta -= 1
- xRem += q
- }
- // Do the first scanline.
- x, yi := x0, y0i
- r.scan(yi, x, y0f, x+xDelta, edge1)
- x, yi = x+xDelta, yi+yiDelta
- r.setCell(int(x)/64, yi)
- if yi != y1i {
- // Do all the intermediate scanlines.
- p = 64 * dx
- fullDelta, fullRem := p/q, p%q
- if fullRem < 0 {
- fullDelta -= 1
- fullRem += q
- }
- xRem -= q
- for yi != y1i {
- xDelta = fullDelta
- xRem += fullRem
- if xRem >= 0 {
- xDelta += 1
- xRem -= q
- }
- r.scan(yi, x, edge0, x+xDelta, edge1)
- x, yi = x+xDelta, yi+yiDelta
- r.setCell(int(x)/64, yi)
- }
- }
- // Do the last scanline.
- r.scan(yi, x, edge0, x1, y1f)
- }
- // The next lineTo starts from b.
- r.a = b
-}
-
-// Add2 adds a quadratic segment to the current curve.
-func (r *Rasterizer) Add2(b, c fixed.Point26_6) {
- // Calculate nSplit (the number of recursive decompositions) based on how
- // 'curvy' it is. Specifically, how much the middle point b deviates from
- // (a+c)/2.
- dev := maxAbs(r.a.X-2*b.X+c.X, r.a.Y-2*b.Y+c.Y) / fixed.Int26_6(r.splitScale2)
- nsplit := 0
- for dev > 0 {
- dev /= 4
- nsplit++
- }
- // dev is 32-bit, and nsplit++ every time we shift off 2 bits, so maxNsplit
- // is 16.
- const maxNsplit = 16
- if nsplit > maxNsplit {
- panic("freetype/raster: Add2 nsplit too large: " + strconv.Itoa(nsplit))
- }
- // Recursively decompose the curve nSplit levels deep.
- var (
- pStack [2*maxNsplit + 3]fixed.Point26_6
- sStack [maxNsplit + 1]int
- i int
- )
- sStack[0] = nsplit
- pStack[0] = c
- pStack[1] = b
- pStack[2] = r.a
- for i >= 0 {
- s := sStack[i]
- p := pStack[2*i:]
- if s > 0 {
- // Split the quadratic curve p[:3] into an equivalent set of two
- // shorter curves: p[:3] and p[2:5]. The new p[4] is the old p[2],
- // and p[0] is unchanged.
- mx := p[1].X
- p[4].X = p[2].X
- p[3].X = (p[4].X + mx) / 2
- p[1].X = (p[0].X + mx) / 2
- p[2].X = (p[1].X + p[3].X) / 2
- my := p[1].Y
- p[4].Y = p[2].Y
- p[3].Y = (p[4].Y + my) / 2
- p[1].Y = (p[0].Y + my) / 2
- p[2].Y = (p[1].Y + p[3].Y) / 2
- // The two shorter curves have one less split to do.
- sStack[i] = s - 1
- sStack[i+1] = s - 1
- i++
- } else {
- // Replace the level-0 quadratic with a two-linear-piece
- // approximation.
- midx := (p[0].X + 2*p[1].X + p[2].X) / 4
- midy := (p[0].Y + 2*p[1].Y + p[2].Y) / 4
- r.Add1(fixed.Point26_6{midx, midy})
- r.Add1(p[0])
- i--
- }
- }
-}
-
-// Add3 adds a cubic segment to the current curve.
-func (r *Rasterizer) Add3(b, c, d fixed.Point26_6) {
- // Calculate nSplit (the number of recursive decompositions) based on how
- // 'curvy' it is.
- dev2 := maxAbs(r.a.X-3*(b.X+c.X)+d.X, r.a.Y-3*(b.Y+c.Y)+d.Y) / fixed.Int26_6(r.splitScale2)
- dev3 := maxAbs(r.a.X-2*b.X+d.X, r.a.Y-2*b.Y+d.Y) / fixed.Int26_6(r.splitScale3)
- nsplit := 0
- for dev2 > 0 || dev3 > 0 {
- dev2 /= 8
- dev3 /= 4
- nsplit++
- }
- // devN is 32-bit, and nsplit++ every time we shift off 2 bits, so
- // maxNsplit is 16.
- const maxNsplit = 16
- if nsplit > maxNsplit {
- panic("freetype/raster: Add3 nsplit too large: " + strconv.Itoa(nsplit))
- }
- // Recursively decompose the curve nSplit levels deep.
- var (
- pStack [3*maxNsplit + 4]fixed.Point26_6
- sStack [maxNsplit + 1]int
- i int
- )
- sStack[0] = nsplit
- pStack[0] = d
- pStack[1] = c
- pStack[2] = b
- pStack[3] = r.a
- for i >= 0 {
- s := sStack[i]
- p := pStack[3*i:]
- if s > 0 {
- // Split the cubic curve p[:4] into an equivalent set of two
- // shorter curves: p[:4] and p[3:7]. The new p[6] is the old p[3],
- // and p[0] is unchanged.
- m01x := (p[0].X + p[1].X) / 2
- m12x := (p[1].X + p[2].X) / 2
- m23x := (p[2].X + p[3].X) / 2
- p[6].X = p[3].X
- p[5].X = m23x
- p[1].X = m01x
- p[2].X = (m01x + m12x) / 2
- p[4].X = (m12x + m23x) / 2
- p[3].X = (p[2].X + p[4].X) / 2
- m01y := (p[0].Y + p[1].Y) / 2
- m12y := (p[1].Y + p[2].Y) / 2
- m23y := (p[2].Y + p[3].Y) / 2
- p[6].Y = p[3].Y
- p[5].Y = m23y
- p[1].Y = m01y
- p[2].Y = (m01y + m12y) / 2
- p[4].Y = (m12y + m23y) / 2
- p[3].Y = (p[2].Y + p[4].Y) / 2
- // The two shorter curves have one less split to do.
- sStack[i] = s - 1
- sStack[i+1] = s - 1
- i++
- } else {
- // Replace the level-0 cubic with a two-linear-piece approximation.
- midx := (p[0].X + 3*(p[1].X+p[2].X) + p[3].X) / 8
- midy := (p[0].Y + 3*(p[1].Y+p[2].Y) + p[3].Y) / 8
- r.Add1(fixed.Point26_6{midx, midy})
- r.Add1(p[0])
- i--
- }
- }
-}
-
-// AddPath adds the given Path.
-func (r *Rasterizer) AddPath(p Path) {
- for i := 0; i < len(p); {
- switch p[i] {
- case 0:
- r.Start(
- fixed.Point26_6{p[i+1], p[i+2]},
- )
- i += 4
- case 1:
- r.Add1(
- fixed.Point26_6{p[i+1], p[i+2]},
- )
- i += 4
- case 2:
- r.Add2(
- fixed.Point26_6{p[i+1], p[i+2]},
- fixed.Point26_6{p[i+3], p[i+4]},
- )
- i += 6
- case 3:
- r.Add3(
- fixed.Point26_6{p[i+1], p[i+2]},
- fixed.Point26_6{p[i+3], p[i+4]},
- fixed.Point26_6{p[i+5], p[i+6]},
- )
- i += 8
- default:
- panic("freetype/raster: bad path")
- }
- }
-}
-
-// AddStroke adds a stroked Path.
-func (r *Rasterizer) AddStroke(q Path, width fixed.Int26_6, cr Capper, jr Joiner) {
- Stroke(r, q, width, cr, jr)
-}
-
-// areaToAlpha converts an area value to a uint32 alpha value. A completely
-// filled pixel corresponds to an area of 64*64*2, and an alpha of 0xffff. The
-// conversion of area values greater than this depends on the winding rule:
-// even-odd or non-zero.
-func (r *Rasterizer) areaToAlpha(area int) uint32 {
- // The C Freetype implementation (version 2.3.12) does "alpha := area>>1"
- // without the +1. Round-to-nearest gives a more symmetric result than
- // round-down. The C implementation also returns 8-bit alpha, not 16-bit
- // alpha.
- a := (area + 1) >> 1
- if a < 0 {
- a = -a
- }
- alpha := uint32(a)
- if r.UseNonZeroWinding {
- if alpha > 0x0fff {
- alpha = 0x0fff
- }
- } else {
- alpha &= 0x1fff
- if alpha > 0x1000 {
- alpha = 0x2000 - alpha
- } else if alpha == 0x1000 {
- alpha = 0x0fff
- }
- }
- // alpha is now in the range [0x0000, 0x0fff]. Convert that 12-bit alpha to
- // 16-bit alpha.
- return alpha<<4 | alpha>>8
-}
-
-// Rasterize converts r's accumulated curves into Spans for p. The Spans passed
-// to p are non-overlapping, and sorted by Y and then X. They all have non-zero
-// width (and 0 <= X0 < X1 <= r.width) and non-zero A, except for the final
-// Span, which has Y, X0, X1 and A all equal to zero.
-func (r *Rasterizer) Rasterize(p Painter) {
- r.saveCell()
- s := 0
- for yi := 0; yi < len(r.cellIndex); yi++ {
- xi, cover := 0, 0
- for c := r.cellIndex[yi]; c != -1; c = r.cell[c].next {
- if cover != 0 && r.cell[c].xi > xi {
- alpha := r.areaToAlpha(cover * 64 * 2)
- if alpha != 0 {
- xi0, xi1 := xi, r.cell[c].xi
- if xi0 < 0 {
- xi0 = 0
- }
- if xi1 >= r.width {
- xi1 = r.width
- }
- if xi0 < xi1 {
- r.spanBuf[s] = Span{yi + r.Dy, xi0 + r.Dx, xi1 + r.Dx, alpha}
- s++
- }
- }
- }
- cover += r.cell[c].cover
- alpha := r.areaToAlpha(cover*64*2 - r.cell[c].area)
- xi = r.cell[c].xi + 1
- if alpha != 0 {
- xi0, xi1 := r.cell[c].xi, xi
- if xi0 < 0 {
- xi0 = 0
- }
- if xi1 >= r.width {
- xi1 = r.width
- }
- if xi0 < xi1 {
- r.spanBuf[s] = Span{yi + r.Dy, xi0 + r.Dx, xi1 + r.Dx, alpha}
- s++
- }
- }
- if s > len(r.spanBuf)-2 {
- p.Paint(r.spanBuf[:s], false)
- s = 0
- }
- }
- }
- p.Paint(r.spanBuf[:s], true)
-}
-
-// Clear cancels any previous calls to r.Start or r.AddXxx.
-func (r *Rasterizer) Clear() {
- r.a = fixed.Point26_6{}
- r.xi = 0
- r.yi = 0
- r.area = 0
- r.cover = 0
- r.cell = r.cell[:0]
- for i := 0; i < len(r.cellIndex); i++ {
- r.cellIndex[i] = -1
- }
-}
-
-// SetBounds sets the maximum width and height of the rasterized image and
-// calls Clear. The width and height are in pixels, not fixed.Int26_6 units.
-func (r *Rasterizer) SetBounds(width, height int) {
- if width < 0 {
- width = 0
- }
- if height < 0 {
- height = 0
- }
- // Use the same ssN heuristic as the C Freetype (version 2.4.0)
- // implementation.
- ss2, ss3 := 32, 16
- if width > 24 || height > 24 {
- ss2, ss3 = 2*ss2, 2*ss3
- if width > 120 || height > 120 {
- ss2, ss3 = 2*ss2, 2*ss3
- }
- }
- r.width = width
- r.splitScale2 = ss2
- r.splitScale3 = ss3
- r.cell = r.cellBuf[:0]
- if height > len(r.cellIndexBuf) {
- r.cellIndex = make([]int, height)
- } else {
- r.cellIndex = r.cellIndexBuf[:height]
- }
- r.Clear()
-}
-
-// NewRasterizer creates a new Rasterizer with the given bounds.
-func NewRasterizer(width, height int) *Rasterizer {
- r := new(Rasterizer)
- r.SetBounds(width, height)
- return r
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/raster/stroke.go b/Godeps/_workspace/src/github.com/golang/freetype/raster/stroke.go
deleted file mode 100644
index 8d4379757..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/raster/stroke.go
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package raster
-
-import (
- "golang.org/x/image/math/fixed"
-)
-
-// Two points are considered practically equal if the square of the distance
-// between them is less than one quarter (i.e. 1024 / 4096).
-const epsilon = fixed.Int52_12(1024)
-
-// A Capper signifies how to begin or end a stroked path.
-type Capper interface {
- // Cap adds a cap to p given a pivot point and the normal vector of a
- // terminal segment. The normal's length is half of the stroke width.
- Cap(p Adder, halfWidth fixed.Int26_6, pivot, n1 fixed.Point26_6)
-}
-
-// The CapperFunc type adapts an ordinary function to be a Capper.
-type CapperFunc func(Adder, fixed.Int26_6, fixed.Point26_6, fixed.Point26_6)
-
-func (f CapperFunc) Cap(p Adder, halfWidth fixed.Int26_6, pivot, n1 fixed.Point26_6) {
- f(p, halfWidth, pivot, n1)
-}
-
-// A Joiner signifies how to join interior nodes of a stroked path.
-type Joiner interface {
- // Join adds a join to the two sides of a stroked path given a pivot
- // point and the normal vectors of the trailing and leading segments.
- // Both normals have length equal to half of the stroke width.
- Join(lhs, rhs Adder, halfWidth fixed.Int26_6, pivot, n0, n1 fixed.Point26_6)
-}
-
-// The JoinerFunc type adapts an ordinary function to be a Joiner.
-type JoinerFunc func(lhs, rhs Adder, halfWidth fixed.Int26_6, pivot, n0, n1 fixed.Point26_6)
-
-func (f JoinerFunc) Join(lhs, rhs Adder, halfWidth fixed.Int26_6, pivot, n0, n1 fixed.Point26_6) {
- f(lhs, rhs, halfWidth, pivot, n0, n1)
-}
-
-// RoundCapper adds round caps to a stroked path.
-var RoundCapper Capper = CapperFunc(roundCapper)
-
-func roundCapper(p Adder, halfWidth fixed.Int26_6, pivot, n1 fixed.Point26_6) {
- // The cubic Bézier approximation to a circle involves the magic number
- // (√2 - 1) * 4/3, which is approximately 141/256.
- const k = 141
- e := pRot90CCW(n1)
- side := pivot.Add(e)
- start, end := pivot.Sub(n1), pivot.Add(n1)
- d, e := n1.Mul(k), e.Mul(k)
- p.Add3(start.Add(e), side.Sub(d), side)
- p.Add3(side.Add(d), end.Add(e), end)
-}
-
-// ButtCapper adds butt caps to a stroked path.
-var ButtCapper Capper = CapperFunc(buttCapper)
-
-func buttCapper(p Adder, halfWidth fixed.Int26_6, pivot, n1 fixed.Point26_6) {
- p.Add1(pivot.Add(n1))
-}
-
-// SquareCapper adds square caps to a stroked path.
-var SquareCapper Capper = CapperFunc(squareCapper)
-
-func squareCapper(p Adder, halfWidth fixed.Int26_6, pivot, n1 fixed.Point26_6) {
- e := pRot90CCW(n1)
- side := pivot.Add(e)
- p.Add1(side.Sub(n1))
- p.Add1(side.Add(n1))
- p.Add1(pivot.Add(n1))
-}
-
-// RoundJoiner adds round joins to a stroked path.
-var RoundJoiner Joiner = JoinerFunc(roundJoiner)
-
-func roundJoiner(lhs, rhs Adder, haflWidth fixed.Int26_6, pivot, n0, n1 fixed.Point26_6) {
- dot := pDot(pRot90CW(n0), n1)
- if dot >= 0 {
- addArc(lhs, pivot, n0, n1)
- rhs.Add1(pivot.Sub(n1))
- } else {
- lhs.Add1(pivot.Add(n1))
- addArc(rhs, pivot, pNeg(n0), pNeg(n1))
- }
-}
-
-// BevelJoiner adds bevel joins to a stroked path.
-var BevelJoiner Joiner = JoinerFunc(bevelJoiner)
-
-func bevelJoiner(lhs, rhs Adder, haflWidth fixed.Int26_6, pivot, n0, n1 fixed.Point26_6) {
- lhs.Add1(pivot.Add(n1))
- rhs.Add1(pivot.Sub(n1))
-}
-
-// addArc adds a circular arc from pivot+n0 to pivot+n1 to p. The shorter of
-// the two possible arcs is taken, i.e. the one spanning <= 180 degrees. The
-// two vectors n0 and n1 must be of equal length.
-func addArc(p Adder, pivot, n0, n1 fixed.Point26_6) {
- // r2 is the square of the length of n0.
- r2 := pDot(n0, n0)
- if r2 < epsilon {
- // The arc radius is so small that we collapse to a straight line.
- p.Add1(pivot.Add(n1))
- return
- }
- // We approximate the arc by 0, 1, 2 or 3 45-degree quadratic segments plus
- // a final quadratic segment from s to n1. Each 45-degree segment has
- // control points {1, 0}, {1, tan(π/8)} and {1/√2, 1/√2} suitably scaled,
- // rotated and translated. tan(Ï€/8) is approximately 106/256.
- const tpo8 = 106
- var s fixed.Point26_6
- // We determine which octant the angle between n0 and n1 is in via three
- // dot products. m0, m1 and m2 are n0 rotated clockwise by 45, 90 and 135
- // degrees.
- m0 := pRot45CW(n0)
- m1 := pRot90CW(n0)
- m2 := pRot90CW(m0)
- if pDot(m1, n1) >= 0 {
- if pDot(n0, n1) >= 0 {
- if pDot(m2, n1) <= 0 {
- // n1 is between 0 and 45 degrees clockwise of n0.
- s = n0
- } else {
- // n1 is between 45 and 90 degrees clockwise of n0.
- p.Add2(pivot.Add(n0).Add(m1.Mul(tpo8)), pivot.Add(m0))
- s = m0
- }
- } else {
- pm1, n0t := pivot.Add(m1), n0.Mul(tpo8)
- p.Add2(pivot.Add(n0).Add(m1.Mul(tpo8)), pivot.Add(m0))
- p.Add2(pm1.Add(n0t), pm1)
- if pDot(m0, n1) >= 0 {
- // n1 is between 90 and 135 degrees clockwise of n0.
- s = m1
- } else {
- // n1 is between 135 and 180 degrees clockwise of n0.
- p.Add2(pm1.Sub(n0t), pivot.Add(m2))
- s = m2
- }
- }
- } else {
- if pDot(n0, n1) >= 0 {
- if pDot(m0, n1) >= 0 {
- // n1 is between 0 and 45 degrees counter-clockwise of n0.
- s = n0
- } else {
- // n1 is between 45 and 90 degrees counter-clockwise of n0.
- p.Add2(pivot.Add(n0).Sub(m1.Mul(tpo8)), pivot.Sub(m2))
- s = pNeg(m2)
- }
- } else {
- pm1, n0t := pivot.Sub(m1), n0.Mul(tpo8)
- p.Add2(pivot.Add(n0).Sub(m1.Mul(tpo8)), pivot.Sub(m2))
- p.Add2(pm1.Add(n0t), pm1)
- if pDot(m2, n1) <= 0 {
- // n1 is between 90 and 135 degrees counter-clockwise of n0.
- s = pNeg(m1)
- } else {
- // n1 is between 135 and 180 degrees counter-clockwise of n0.
- p.Add2(pm1.Sub(n0t), pivot.Sub(m0))
- s = pNeg(m0)
- }
- }
- }
- // The final quadratic segment has two endpoints s and n1 and the middle
- // control point is a multiple of s.Add(n1), i.e. it is on the angle
- // bisector of those two points. The multiple ranges between 128/256 and
- // 150/256 as the angle between s and n1 ranges between 0 and 45 degrees.
- //
- // When the angle is 0 degrees (i.e. s and n1 are coincident) then
- // s.Add(n1) is twice s and so the middle control point of the degenerate
- // quadratic segment should be half s.Add(n1), and half = 128/256.
- //
- // When the angle is 45 degrees then 150/256 is the ratio of the lengths of
- // the two vectors {1, tan(π/8)} and {1 + 1/√2, 1/√2}.
- //
- // d is the normalized dot product between s and n1. Since the angle ranges
- // between 0 and 45 degrees then d ranges between 256/256 and 181/256.
- d := 256 * pDot(s, n1) / r2
- multiple := fixed.Int26_6(150-(150-128)*(d-181)/(256-181)) >> 2
- p.Add2(pivot.Add(s.Add(n1).Mul(multiple)), pivot.Add(n1))
-}
-
-// midpoint returns the midpoint of two Points.
-func midpoint(a, b fixed.Point26_6) fixed.Point26_6 {
- return fixed.Point26_6{(a.X + b.X) / 2, (a.Y + b.Y) / 2}
-}
-
-// angleGreaterThan45 returns whether the angle between two vectors is more
-// than 45 degrees.
-func angleGreaterThan45(v0, v1 fixed.Point26_6) bool {
- v := pRot45CCW(v0)
- return pDot(v, v1) < 0 || pDot(pRot90CW(v), v1) < 0
-}
-
-// interpolate returns the point (1-t)*a + t*b.
-func interpolate(a, b fixed.Point26_6, t fixed.Int52_12) fixed.Point26_6 {
- s := 1<<12 - t
- x := s*fixed.Int52_12(a.X) + t*fixed.Int52_12(b.X)
- y := s*fixed.Int52_12(a.Y) + t*fixed.Int52_12(b.Y)
- return fixed.Point26_6{fixed.Int26_6(x >> 12), fixed.Int26_6(y >> 12)}
-}
-
-// curviest2 returns the value of t for which the quadratic parametric curve
-// (1-t)²*a + 2*t*(1-t).b + t²*c has maximum curvature.
-//
-// The curvature of the parametric curve f(t) = (x(t), y(t)) is
-// |x′y″-y′x″| / (x′²+y′²)^(3/2).
-//
-// Let d = b-a and e = c-2*b+a, so that f′(t) = 2*d+2*e*t and f″(t) = 2*e.
-// The curvature's numerator is (2*dx+2*ex*t)*(2*ey)-(2*dy+2*ey*t)*(2*ex),
-// which simplifies to 4*dx*ey-4*dy*ex, which is constant with respect to t.
-//
-// Thus, curvature is extreme where the denominator is extreme, i.e. where
-// (x′²+y′²) is extreme. The first order condition is that
-// 2*x′*x″+2*y′*y″ = 0, or (dx+ex*t)*ex + (dy+ey*t)*ey = 0.
-// Solving for t gives t = -(dx*ex+dy*ey) / (ex*ex+ey*ey).
-func curviest2(a, b, c fixed.Point26_6) fixed.Int52_12 {
- dx := int64(b.X - a.X)
- dy := int64(b.Y - a.Y)
- ex := int64(c.X - 2*b.X + a.X)
- ey := int64(c.Y - 2*b.Y + a.Y)
- if ex == 0 && ey == 0 {
- return 2048
- }
- return fixed.Int52_12(-4096 * (dx*ex + dy*ey) / (ex*ex + ey*ey))
-}
-
-// A stroker holds state for stroking a path.
-type stroker struct {
- // p is the destination that records the stroked path.
- p Adder
- // u is the half-width of the stroke.
- u fixed.Int26_6
- // cr and jr specify how to end and connect path segments.
- cr Capper
- jr Joiner
- // r is the reverse path. Stroking a path involves constructing two
- // parallel paths 2*u apart. The first path is added immediately to p,
- // the second path is accumulated in r and eventually added in reverse.
- r Path
- // a is the most recent segment point. anorm is the segment normal of
- // length u at that point.
- a, anorm fixed.Point26_6
-}
-
-// addNonCurvy2 adds a quadratic segment to the stroker, where the segment
-// defined by (k.a, b, c) achieves maximum curvature at either k.a or c.
-func (k *stroker) addNonCurvy2(b, c fixed.Point26_6) {
- // We repeatedly divide the segment at its middle until it is straight
- // enough to approximate the stroke by just translating the control points.
- // ds and ps are stacks of depths and points. t is the top of the stack.
- const maxDepth = 5
- var (
- ds [maxDepth + 1]int
- ps [2*maxDepth + 3]fixed.Point26_6
- t int
- )
- // Initially the ps stack has one quadratic segment of depth zero.
- ds[0] = 0
- ps[2] = k.a
- ps[1] = b
- ps[0] = c
- anorm := k.anorm
- var cnorm fixed.Point26_6
-
- for {
- depth := ds[t]
- a := ps[2*t+2]
- b := ps[2*t+1]
- c := ps[2*t+0]
- ab := b.Sub(a)
- bc := c.Sub(b)
- abIsSmall := pDot(ab, ab) < fixed.Int52_12(1<<12)
- bcIsSmall := pDot(bc, bc) < fixed.Int52_12(1<<12)
- if abIsSmall && bcIsSmall {
- // Approximate the segment by a circular arc.
- cnorm = pRot90CCW(pNorm(bc, k.u))
- mac := midpoint(a, c)
- addArc(k.p, mac, anorm, cnorm)
- addArc(&k.r, mac, pNeg(anorm), pNeg(cnorm))
- } else if depth < maxDepth && angleGreaterThan45(ab, bc) {
- // Divide the segment in two and push both halves on the stack.
- mab := midpoint(a, b)
- mbc := midpoint(b, c)
- t++
- ds[t+0] = depth + 1
- ds[t-1] = depth + 1
- ps[2*t+2] = a
- ps[2*t+1] = mab
- ps[2*t+0] = midpoint(mab, mbc)
- ps[2*t-1] = mbc
- continue
- } else {
- // Translate the control points.
- bnorm := pRot90CCW(pNorm(c.Sub(a), k.u))
- cnorm = pRot90CCW(pNorm(bc, k.u))
- k.p.Add2(b.Add(bnorm), c.Add(cnorm))
- k.r.Add2(b.Sub(bnorm), c.Sub(cnorm))
- }
- if t == 0 {
- k.a, k.anorm = c, cnorm
- return
- }
- t--
- anorm = cnorm
- }
- panic("unreachable")
-}
-
-// Add1 adds a linear segment to the stroker.
-func (k *stroker) Add1(b fixed.Point26_6) {
- bnorm := pRot90CCW(pNorm(b.Sub(k.a), k.u))
- if len(k.r) == 0 {
- k.p.Start(k.a.Add(bnorm))
- k.r.Start(k.a.Sub(bnorm))
- } else {
- k.jr.Join(k.p, &k.r, k.u, k.a, k.anorm, bnorm)
- }
- k.p.Add1(b.Add(bnorm))
- k.r.Add1(b.Sub(bnorm))
- k.a, k.anorm = b, bnorm
-}
-
-// Add2 adds a quadratic segment to the stroker.
-func (k *stroker) Add2(b, c fixed.Point26_6) {
- ab := b.Sub(k.a)
- bc := c.Sub(b)
- abnorm := pRot90CCW(pNorm(ab, k.u))
- if len(k.r) == 0 {
- k.p.Start(k.a.Add(abnorm))
- k.r.Start(k.a.Sub(abnorm))
- } else {
- k.jr.Join(k.p, &k.r, k.u, k.a, k.anorm, abnorm)
- }
-
- // Approximate nearly-degenerate quadratics by linear segments.
- abIsSmall := pDot(ab, ab) < epsilon
- bcIsSmall := pDot(bc, bc) < epsilon
- if abIsSmall || bcIsSmall {
- acnorm := pRot90CCW(pNorm(c.Sub(k.a), k.u))
- k.p.Add1(c.Add(acnorm))
- k.r.Add1(c.Sub(acnorm))
- k.a, k.anorm = c, acnorm
- return
- }
-
- // The quadratic segment (k.a, b, c) has a point of maximum curvature.
- // If this occurs at an end point, we process the segment as a whole.
- t := curviest2(k.a, b, c)
- if t <= 0 || 4096 <= t {
- k.addNonCurvy2(b, c)
- return
- }
-
- // Otherwise, we perform a de Casteljau decomposition at the point of
- // maximum curvature and process the two straighter parts.
- mab := interpolate(k.a, b, t)
- mbc := interpolate(b, c, t)
- mabc := interpolate(mab, mbc, t)
-
- // If the vectors ab and bc are close to being in opposite directions,
- // then the decomposition can become unstable, so we approximate the
- // quadratic segment by two linear segments joined by an arc.
- bcnorm := pRot90CCW(pNorm(bc, k.u))
- if pDot(abnorm, bcnorm) < -fixed.Int52_12(k.u)*fixed.Int52_12(k.u)*2047/2048 {
- pArc := pDot(abnorm, bc) < 0
-
- k.p.Add1(mabc.Add(abnorm))
- if pArc {
- z := pRot90CW(abnorm)
- addArc(k.p, mabc, abnorm, z)
- addArc(k.p, mabc, z, bcnorm)
- }
- k.p.Add1(mabc.Add(bcnorm))
- k.p.Add1(c.Add(bcnorm))
-
- k.r.Add1(mabc.Sub(abnorm))
- if !pArc {
- z := pRot90CW(abnorm)
- addArc(&k.r, mabc, pNeg(abnorm), z)
- addArc(&k.r, mabc, z, pNeg(bcnorm))
- }
- k.r.Add1(mabc.Sub(bcnorm))
- k.r.Add1(c.Sub(bcnorm))
-
- k.a, k.anorm = c, bcnorm
- return
- }
-
- // Process the decomposed parts.
- k.addNonCurvy2(mab, mabc)
- k.addNonCurvy2(mbc, c)
-}
-
-// Add3 adds a cubic segment to the stroker.
-func (k *stroker) Add3(b, c, d fixed.Point26_6) {
- panic("freetype/raster: stroke unimplemented for cubic segments")
-}
-
-// stroke adds the stroked Path q to p, where q consists of exactly one curve.
-func (k *stroker) stroke(q Path) {
- // Stroking is implemented by deriving two paths each k.u apart from q.
- // The left-hand-side path is added immediately to k.p; the right-hand-side
- // path is accumulated in k.r. Once we've finished adding the LHS to k.p,
- // we add the RHS in reverse order.
- k.r = make(Path, 0, len(q))
- k.a = fixed.Point26_6{q[1], q[2]}
- for i := 4; i < len(q); {
- switch q[i] {
- case 1:
- k.Add1(
- fixed.Point26_6{q[i+1], q[i+2]},
- )
- i += 4
- case 2:
- k.Add2(
- fixed.Point26_6{q[i+1], q[i+2]},
- fixed.Point26_6{q[i+3], q[i+4]},
- )
- i += 6
- case 3:
- k.Add3(
- fixed.Point26_6{q[i+1], q[i+2]},
- fixed.Point26_6{q[i+3], q[i+4]},
- fixed.Point26_6{q[i+5], q[i+6]},
- )
- i += 8
- default:
- panic("freetype/raster: bad path")
- }
- }
- if len(k.r) == 0 {
- return
- }
- // TODO(nigeltao): if q is a closed curve then we should join the first and
- // last segments instead of capping them.
- k.cr.Cap(k.p, k.u, q.lastPoint(), pNeg(k.anorm))
- addPathReversed(k.p, k.r)
- pivot := q.firstPoint()
- k.cr.Cap(k.p, k.u, pivot, pivot.Sub(fixed.Point26_6{k.r[1], k.r[2]}))
-}
-
-// Stroke adds q stroked with the given width to p. The result is typically
-// self-intersecting and should be rasterized with UseNonZeroWinding.
-// cr and jr may be nil, which defaults to a RoundCapper or RoundJoiner.
-func Stroke(p Adder, q Path, width fixed.Int26_6, cr Capper, jr Joiner) {
- if len(q) == 0 {
- return
- }
- if cr == nil {
- cr = RoundCapper
- }
- if jr == nil {
- jr = RoundJoiner
- }
- if q[0] != 0 {
- panic("freetype/raster: bad path")
- }
- s := stroker{p: p, u: width / 2, cr: cr, jr: jr}
- i := 0
- for j := 4; j < len(q); {
- switch q[j] {
- case 0:
- s.stroke(q[i:j])
- i, j = j, j+4
- case 1:
- j += 4
- case 2:
- j += 6
- case 3:
- j += 8
- default:
- panic("freetype/raster: bad path")
- }
- }
- s.stroke(q[i:])
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/face.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/face.go
deleted file mode 100644
index d64a014c3..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/face.go
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright 2015 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-import (
- "image"
-
- "github.com/golang/freetype/raster"
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-func powerOf2(i int) bool {
- return i != 0 && (i&(i-1)) == 0
-}
-
-// Options are optional arguments to NewFace.
-type Options struct {
- // Size is the font size in points, as in "a 10 point font size".
- //
- // A zero value means to use a 12 point font size.
- Size float64
-
- // DPI is the dots-per-inch resolution.
- //
- // A zero value means to use 72 DPI.
- DPI float64
-
- // Hinting is how to quantize the glyph nodes.
- //
- // A zero value means to use no hinting.
- Hinting font.Hinting
-
- // GlyphCacheEntries is the number of entries in the glyph mask image
- // cache.
- //
- // If non-zero, it must be a power of 2.
- //
- // A zero value means to use 512 entries.
- GlyphCacheEntries int
-
- // SubPixelsX is the number of sub-pixel locations a glyph's dot is
- // quantized to, in the horizontal direction. For example, a value of 8
- // means that the dot is quantized to 1/8th of a pixel. This quantization
- // only affects the glyph mask image, not its bounding box or advance
- // width. A higher value gives a more faithful glyph image, but reduces the
- // effectiveness of the glyph cache.
- //
- // If non-zero, it must be a power of 2, and be between 1 and 64 inclusive.
- //
- // A zero value means to use 4 sub-pixel locations.
- SubPixelsX int
-
- // SubPixelsY is the number of sub-pixel locations a glyph's dot is
- // quantized to, in the vertical direction. For example, a value of 8
- // means that the dot is quantized to 1/8th of a pixel. This quantization
- // only affects the glyph mask image, not its bounding box or advance
- // width. A higher value gives a more faithful glyph image, but reduces the
- // effectiveness of the glyph cache.
- //
- // If non-zero, it must be a power of 2, and be between 1 and 64 inclusive.
- //
- // A zero value means to use 1 sub-pixel location.
- SubPixelsY int
-}
-
-func (o *Options) size() float64 {
- if o != nil && o.Size > 0 {
- return o.Size
- }
- return 12
-}
-
-func (o *Options) dpi() float64 {
- if o != nil && o.DPI > 0 {
- return o.DPI
- }
- return 72
-}
-
-func (o *Options) hinting() font.Hinting {
- if o != nil {
- switch o.Hinting {
- case font.HintingVertical, font.HintingFull:
- // TODO: support vertical hinting.
- return font.HintingFull
- }
- }
- return font.HintingNone
-}
-
-func (o *Options) glyphCacheEntries() int {
- if o != nil && powerOf2(o.GlyphCacheEntries) {
- return o.GlyphCacheEntries
- }
- // 512 is 128 * 4 * 1, which lets us cache 128 glyphs at 4 * 1 subpixel
- // locations in the X and Y direction.
- return 512
-}
-
-func (o *Options) subPixelsX() (value uint32, halfQuantum, mask fixed.Int26_6) {
- if o != nil {
- switch o.SubPixelsX {
- case 1, 2, 4, 8, 16, 32, 64:
- return subPixels(o.SubPixelsX)
- }
- }
- // This default value of 4 isn't based on anything scientific, merely as
- // small a number as possible that looks almost as good as no quantization,
- // or returning subPixels(64).
- return subPixels(4)
-}
-
-func (o *Options) subPixelsY() (value uint32, halfQuantum, mask fixed.Int26_6) {
- if o != nil {
- switch o.SubPixelsX {
- case 1, 2, 4, 8, 16, 32, 64:
- return subPixels(o.SubPixelsX)
- }
- }
- // This default value of 1 isn't based on anything scientific, merely that
- // vertical sub-pixel glyph rendering is pretty rare. Baseline locations
- // can usually afford to snap to the pixel grid, so the vertical direction
- // doesn't have the deal with the horizontal's fractional advance widths.
- return subPixels(1)
-}
-
-// subPixels returns q and the bias and mask that leads to q quantized
-// sub-pixel locations per full pixel.
-//
-// For example, q == 4 leads to a bias of 8 and a mask of 0xfffffff0, or -16,
-// because we want to round fractions of fixed.Int26_6 as:
-// - 0 to 7 rounds to 0.
-// - 8 to 23 rounds to 16.
-// - 24 to 39 rounds to 32.
-// - 40 to 55 rounds to 48.
-// - 56 to 63 rounds to 64.
-// which means to add 8 and then bitwise-and with -16, in two's complement
-// representation.
-//
-// When q == 1, we want bias == 32 and mask == -64.
-// When q == 2, we want bias == 16 and mask == -32.
-// When q == 4, we want bias == 8 and mask == -16.
-// ...
-// When q == 64, we want bias == 0 and mask == -1. (The no-op case).
-// The pattern is clear.
-func subPixels(q int) (value uint32, bias, mask fixed.Int26_6) {
- return uint32(q), 32 / fixed.Int26_6(q), -64 / fixed.Int26_6(q)
-}
-
-// glyphCacheEntry caches the arguments and return values of rasterize.
-type glyphCacheEntry struct {
- key glyphCacheKey
- val glyphCacheVal
-}
-
-type glyphCacheKey struct {
- index Index
- fx, fy uint8
-}
-
-type glyphCacheVal struct {
- advanceWidth fixed.Int26_6
- offset image.Point
- gw int
- gh int
-}
-
-type indexCacheEntry struct {
- rune rune
- index Index
-}
-
-// NewFace returns a new font.Face for the given Font.
-func NewFace(f *Font, opts *Options) font.Face {
- a := &face{
- f: f,
- hinting: opts.hinting(),
- scale: fixed.Int26_6(0.5 + (opts.size() * opts.dpi() * 64 / 72)),
- glyphCache: make([]glyphCacheEntry, opts.glyphCacheEntries()),
- }
- a.subPixelX, a.subPixelBiasX, a.subPixelMaskX = opts.subPixelsX()
- a.subPixelY, a.subPixelBiasY, a.subPixelMaskY = opts.subPixelsY()
-
- // Fill the cache with invalid entries. Valid glyph cache entries have fx
- // and fy in the range [0, 64). Valid index cache entries have rune >= 0.
- for i := range a.glyphCache {
- a.glyphCache[i].key.fy = 0xff
- }
- for i := range a.indexCache {
- a.indexCache[i].rune = -1
- }
-
- // Set the rasterizer's bounds to be big enough to handle the largest glyph.
- b := f.Bounds(a.scale)
- xmin := +int(b.Min.X) >> 6
- ymin := -int(b.Max.Y) >> 6
- xmax := +int(b.Max.X+63) >> 6
- ymax := -int(b.Min.Y-63) >> 6
- a.maxw = xmax - xmin
- a.maxh = ymax - ymin
- a.masks = image.NewAlpha(image.Rect(0, 0, a.maxw, a.maxh*len(a.glyphCache)))
- a.r.SetBounds(a.maxw, a.maxh)
- a.p = facePainter{a}
-
- return a
-}
-
-type face struct {
- f *Font
- hinting font.Hinting
- scale fixed.Int26_6
- subPixelX uint32
- subPixelBiasX fixed.Int26_6
- subPixelMaskX fixed.Int26_6
- subPixelY uint32
- subPixelBiasY fixed.Int26_6
- subPixelMaskY fixed.Int26_6
- masks *image.Alpha
- glyphCache []glyphCacheEntry
- r raster.Rasterizer
- p raster.Painter
- paintOffset int
- maxw int
- maxh int
- glyphBuf GlyphBuf
- indexCache [indexCacheLen]indexCacheEntry
-
- // TODO: clip rectangle?
-}
-
-const indexCacheLen = 256
-
-func (a *face) index(r rune) Index {
- const mask = indexCacheLen - 1
- c := &a.indexCache[r&mask]
- if c.rune == r {
- return c.index
- }
- i := a.f.Index(r)
- c.rune = r
- c.index = i
- return i
-}
-
-// Close satisfies the font.Face interface.
-func (a *face) Close() error { return nil }
-
-// Kern satisfies the font.Face interface.
-func (a *face) Kern(r0, r1 rune) fixed.Int26_6 {
- i0 := a.index(r0)
- i1 := a.index(r1)
- kern := a.f.Kern(a.scale, i0, i1)
- if a.hinting != font.HintingNone {
- kern = (kern + 32) &^ 63
- }
- return kern
-}
-
-// Glyph satisfies the font.Face interface.
-func (a *face) Glyph(dot fixed.Point26_6, r rune) (
- dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
-
- // Quantize to the sub-pixel granularity.
- dotX := (dot.X + a.subPixelBiasX) & a.subPixelMaskX
- dotY := (dot.Y + a.subPixelBiasY) & a.subPixelMaskY
-
- // Split the coordinates into their integer and fractional parts.
- ix, fx := int(dotX>>6), dotX&0x3f
- iy, fy := int(dotY>>6), dotY&0x3f
-
- index := a.index(r)
- cIndex := uint32(index)
- cIndex = cIndex*a.subPixelX - uint32(fx/a.subPixelMaskX)
- cIndex = cIndex*a.subPixelY - uint32(fy/a.subPixelMaskY)
- cIndex &= uint32(len(a.glyphCache) - 1)
- a.paintOffset = a.maxh * int(cIndex)
- k := glyphCacheKey{
- index: index,
- fx: uint8(fx),
- fy: uint8(fy),
- }
- var v glyphCacheVal
- if a.glyphCache[cIndex].key != k {
- var ok bool
- v, ok = a.rasterize(index, fx, fy)
- if !ok {
- return image.Rectangle{}, nil, image.Point{}, 0, false
- }
- a.glyphCache[cIndex] = glyphCacheEntry{k, v}
- } else {
- v = a.glyphCache[cIndex].val
- }
-
- dr.Min = image.Point{
- X: ix + v.offset.X,
- Y: iy + v.offset.Y,
- }
- dr.Max = image.Point{
- X: dr.Min.X + v.gw,
- Y: dr.Min.Y + v.gh,
- }
- return dr, a.masks, image.Point{Y: a.paintOffset}, v.advanceWidth, true
-}
-
-func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
- if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil {
- return fixed.Rectangle26_6{}, 0, false
- }
- xmin := +a.glyphBuf.Bounds.Min.X
- ymin := -a.glyphBuf.Bounds.Max.Y
- xmax := +a.glyphBuf.Bounds.Max.X
- ymax := -a.glyphBuf.Bounds.Min.Y
- if xmin > xmax || ymin > ymax {
- return fixed.Rectangle26_6{}, 0, false
- }
- return fixed.Rectangle26_6{
- Min: fixed.Point26_6{
- X: xmin,
- Y: ymin,
- },
- Max: fixed.Point26_6{
- X: xmax,
- Y: ymax,
- },
- }, a.glyphBuf.AdvanceWidth, true
-}
-
-func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
- if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil {
- return 0, false
- }
- return a.glyphBuf.AdvanceWidth, true
-}
-
-// rasterize returns the advance width, integer-pixel offset to render at, and
-// the width and height of the given glyph at the given sub-pixel offsets.
-//
-// The 26.6 fixed point arguments fx and fy must be in the range [0, 1).
-func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (v glyphCacheVal, ok bool) {
- if err := a.glyphBuf.Load(a.f, a.scale, index, a.hinting); err != nil {
- return glyphCacheVal{}, false
- }
- // Calculate the integer-pixel bounds for the glyph.
- xmin := int(fx+a.glyphBuf.Bounds.Min.X) >> 6
- ymin := int(fy-a.glyphBuf.Bounds.Max.Y) >> 6
- xmax := int(fx+a.glyphBuf.Bounds.Max.X+0x3f) >> 6
- ymax := int(fy-a.glyphBuf.Bounds.Min.Y+0x3f) >> 6
- if xmin > xmax || ymin > ymax {
- return glyphCacheVal{}, false
- }
- // A TrueType's glyph's nodes can have negative co-ordinates, but the
- // rasterizer clips anything left of x=0 or above y=0. xmin and ymin are
- // the pixel offsets, based on the font's FUnit metrics, that let a
- // negative co-ordinate in TrueType space be non-negative in rasterizer
- // space. xmin and ymin are typically <= 0.
- fx -= fixed.Int26_6(xmin << 6)
- fy -= fixed.Int26_6(ymin << 6)
- // Rasterize the glyph's vectors.
- a.r.Clear()
- pixOffset := a.paintOffset * a.maxw
- clear(a.masks.Pix[pixOffset : pixOffset+a.maxw*a.maxh])
- e0 := 0
- for _, e1 := range a.glyphBuf.Ends {
- a.drawContour(a.glyphBuf.Points[e0:e1], fx, fy)
- e0 = e1
- }
- a.r.Rasterize(a.p)
- return glyphCacheVal{
- a.glyphBuf.AdvanceWidth,
- image.Point{xmin, ymin},
- xmax - xmin,
- ymax - ymin,
- }, true
-}
-
-func clear(pix []byte) {
- for i := range pix {
- pix[i] = 0
- }
-}
-
-// drawContour draws the given closed contour with the given offset.
-func (a *face) drawContour(ps []Point, dx, dy fixed.Int26_6) {
- if len(ps) == 0 {
- return
- }
-
- // The low bit of each point's Flags value is whether the point is on the
- // curve. Truetype fonts only have quadratic Bézier curves, not cubics.
- // Thus, two consecutive off-curve points imply an on-curve point in the
- // middle of those two.
- //
- // See http://chanae.walon.org/pub/ttf/ttf_glyphs.htm for more details.
-
- // ps[0] is a truetype.Point measured in FUnits and positive Y going
- // upwards. start is the same thing measured in fixed point units and
- // positive Y going downwards, and offset by (dx, dy).
- start := fixed.Point26_6{
- X: dx + ps[0].X,
- Y: dy - ps[0].Y,
- }
- var others []Point
- if ps[0].Flags&0x01 != 0 {
- others = ps[1:]
- } else {
- last := fixed.Point26_6{
- X: dx + ps[len(ps)-1].X,
- Y: dy - ps[len(ps)-1].Y,
- }
- if ps[len(ps)-1].Flags&0x01 != 0 {
- start = last
- others = ps[:len(ps)-1]
- } else {
- start = fixed.Point26_6{
- X: (start.X + last.X) / 2,
- Y: (start.Y + last.Y) / 2,
- }
- others = ps
- }
- }
- a.r.Start(start)
- q0, on0 := start, true
- for _, p := range others {
- q := fixed.Point26_6{
- X: dx + p.X,
- Y: dy - p.Y,
- }
- on := p.Flags&0x01 != 0
- if on {
- if on0 {
- a.r.Add1(q)
- } else {
- a.r.Add2(q0, q)
- }
- } else {
- if on0 {
- // No-op.
- } else {
- mid := fixed.Point26_6{
- X: (q0.X + q.X) / 2,
- Y: (q0.Y + q.Y) / 2,
- }
- a.r.Add2(q0, mid)
- }
- }
- q0, on0 = q, on
- }
- // Close the curve.
- if on0 {
- a.r.Add1(start)
- } else {
- a.r.Add2(q0, start)
- }
-}
-
-// facePainter is like a raster.AlphaSrcPainter, with an additional Y offset
-// (face.paintOffset) to the painted spans.
-type facePainter struct {
- a *face
-}
-
-func (p facePainter) Paint(ss []raster.Span, done bool) {
- m := p.a.masks
- b := m.Bounds()
- b.Min.Y = p.a.paintOffset
- b.Max.Y = p.a.paintOffset + p.a.maxh
- for _, s := range ss {
- s.Y += p.a.paintOffset
- if s.Y < b.Min.Y {
- continue
- }
- if s.Y >= b.Max.Y {
- return
- }
- if s.X0 < b.Min.X {
- s.X0 = b.Min.X
- }
- if s.X1 > b.Max.X {
- s.X1 = b.Max.X
- }
- if s.X0 >= s.X1 {
- continue
- }
- base := (s.Y-m.Rect.Min.Y)*m.Stride - m.Rect.Min.X
- p := m.Pix[base+s.X0 : base+s.X1]
- color := uint8(s.Alpha >> 8)
- for i := range p {
- p[i] = color
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/glyph.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/glyph.go
deleted file mode 100644
index c2935a58e..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/glyph.go
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-import (
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-// TODO: implement VerticalHinting.
-
-// A Point is a co-ordinate pair plus whether it is 'on' a contour or an 'off'
-// control point.
-type Point struct {
- X, Y fixed.Int26_6
- // The Flags' LSB means whether or not this Point is 'on' the contour.
- // Other bits are reserved for internal use.
- Flags uint32
-}
-
-// A GlyphBuf holds a glyph's contours. A GlyphBuf can be re-used to load a
-// series of glyphs from a Font.
-type GlyphBuf struct {
- // AdvanceWidth is the glyph's advance width.
- AdvanceWidth fixed.Int26_6
- // Bounds is the glyph's bounding box.
- Bounds fixed.Rectangle26_6
- // Points contains all Points from all contours of the glyph. If hinting
- // was used to load a glyph then Unhinted contains those Points before they
- // were hinted, and InFontUnits contains those Points before they were
- // hinted and scaled.
- Points, Unhinted, InFontUnits []Point
- // Ends is the point indexes of the end point of each contour. The length
- // of Ends is the number of contours in the glyph. The i'th contour
- // consists of points Points[Ends[i-1]:Ends[i]], where Ends[-1] is
- // interpreted to mean zero.
- Ends []int
-
- font *Font
- scale fixed.Int26_6
- hinting font.Hinting
- hinter hinter
- // phantomPoints are the co-ordinates of the synthetic phantom points
- // used for hinting and bounding box calculations.
- phantomPoints [4]Point
- // pp1x is the X co-ordinate of the first phantom point. The '1' is
- // using 1-based indexing; pp1x is almost always phantomPoints[0].X.
- // TODO: eliminate this and consistently use phantomPoints[0].X.
- pp1x fixed.Int26_6
- // metricsSet is whether the glyph's metrics have been set yet. For a
- // compound glyph, a sub-glyph may override the outer glyph's metrics.
- metricsSet bool
- // tmp is a scratch buffer.
- tmp []Point
-}
-
-// Flags for decoding a glyph's contours. These flags are documented at
-// http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html.
-const (
- flagOnCurve = 1 << iota
- flagXShortVector
- flagYShortVector
- flagRepeat
- flagPositiveXShortVector
- flagPositiveYShortVector
-
- // The remaining flags are for internal use.
- flagTouchedX
- flagTouchedY
-)
-
-// The same flag bits (0x10 and 0x20) are overloaded to have two meanings,
-// dependent on the value of the flag{X,Y}ShortVector bits.
-const (
- flagThisXIsSame = flagPositiveXShortVector
- flagThisYIsSame = flagPositiveYShortVector
-)
-
-// Load loads a glyph's contours from a Font, overwriting any previously loaded
-// contours for this GlyphBuf. scale is the number of 26.6 fixed point units in
-// 1 em, i is the glyph index, and h is the hinting policy.
-func (g *GlyphBuf) Load(f *Font, scale fixed.Int26_6, i Index, h font.Hinting) error {
- g.Points = g.Points[:0]
- g.Unhinted = g.Unhinted[:0]
- g.InFontUnits = g.InFontUnits[:0]
- g.Ends = g.Ends[:0]
- g.font = f
- g.hinting = h
- g.scale = scale
- g.pp1x = 0
- g.phantomPoints = [4]Point{}
- g.metricsSet = false
-
- if h != font.HintingNone {
- if err := g.hinter.init(f, scale); err != nil {
- return err
- }
- }
- if err := g.load(0, i, true); err != nil {
- return err
- }
- // TODO: this selection of either g.pp1x or g.phantomPoints[0].X isn't ideal,
- // and should be cleaned up once we have all the testScaling tests passing,
- // plus additional tests for Freetype-Go's bounding boxes matching C Freetype's.
- pp1x := g.pp1x
- if h != font.HintingNone {
- pp1x = g.phantomPoints[0].X
- }
- if pp1x != 0 {
- for i := range g.Points {
- g.Points[i].X -= pp1x
- }
- }
-
- advanceWidth := g.phantomPoints[1].X - g.phantomPoints[0].X
- if h != font.HintingNone {
- if len(f.hdmx) >= 8 {
- if n := u32(f.hdmx, 4); n > 3+uint32(i) {
- for hdmx := f.hdmx[8:]; uint32(len(hdmx)) >= n; hdmx = hdmx[n:] {
- if fixed.Int26_6(hdmx[0]) == scale>>6 {
- advanceWidth = fixed.Int26_6(hdmx[2+i]) << 6
- break
- }
- }
- }
- }
- advanceWidth = (advanceWidth + 32) &^ 63
- }
- g.AdvanceWidth = advanceWidth
-
- // Set g.Bounds to the 'control box', which is the bounding box of the
- // Bézier curves' control points. This is easier to calculate, no smaller
- // than and often equal to the tightest possible bounding box of the curves
- // themselves. This approach is what C Freetype does. We can't just scale
- // the nominal bounding box in the glyf data as the hinting process and
- // phantom point adjustment may move points outside of that box.
- if len(g.Points) == 0 {
- g.Bounds = fixed.Rectangle26_6{}
- } else {
- p := g.Points[0]
- g.Bounds.Min.X = p.X
- g.Bounds.Max.X = p.X
- g.Bounds.Min.Y = p.Y
- g.Bounds.Max.Y = p.Y
- for _, p := range g.Points[1:] {
- if g.Bounds.Min.X > p.X {
- g.Bounds.Min.X = p.X
- } else if g.Bounds.Max.X < p.X {
- g.Bounds.Max.X = p.X
- }
- if g.Bounds.Min.Y > p.Y {
- g.Bounds.Min.Y = p.Y
- } else if g.Bounds.Max.Y < p.Y {
- g.Bounds.Max.Y = p.Y
- }
- }
- // Snap the box to the grid, if hinting is on.
- if h != font.HintingNone {
- g.Bounds.Min.X &^= 63
- g.Bounds.Min.Y &^= 63
- g.Bounds.Max.X += 63
- g.Bounds.Max.X &^= 63
- g.Bounds.Max.Y += 63
- g.Bounds.Max.Y &^= 63
- }
- }
- return nil
-}
-
-func (g *GlyphBuf) load(recursion uint32, i Index, useMyMetrics bool) (err error) {
- // The recursion limit here is arbitrary, but defends against malformed glyphs.
- if recursion >= 32 {
- return UnsupportedError("excessive compound glyph recursion")
- }
- // Find the relevant slice of g.font.glyf.
- var g0, g1 uint32
- if g.font.locaOffsetFormat == locaOffsetFormatShort {
- g0 = 2 * uint32(u16(g.font.loca, 2*int(i)))
- g1 = 2 * uint32(u16(g.font.loca, 2*int(i)+2))
- } else {
- g0 = u32(g.font.loca, 4*int(i))
- g1 = u32(g.font.loca, 4*int(i)+4)
- }
-
- // Decode the contour count and nominal bounding box, from the first
- // 10 bytes of the glyf data. boundsYMin and boundsXMax, at offsets 4
- // and 6, are unused.
- glyf, ne, boundsXMin, boundsYMax := []byte(nil), 0, fixed.Int26_6(0), fixed.Int26_6(0)
- if g0+10 <= g1 {
- glyf = g.font.glyf[g0:g1]
- ne = int(int16(u16(glyf, 0)))
- boundsXMin = fixed.Int26_6(int16(u16(glyf, 2)))
- boundsYMax = fixed.Int26_6(int16(u16(glyf, 8)))
- }
-
- // Create the phantom points.
- uhm, pp1x := g.font.unscaledHMetric(i), fixed.Int26_6(0)
- uvm := g.font.unscaledVMetric(i, boundsYMax)
- g.phantomPoints = [4]Point{
- {X: boundsXMin - uhm.LeftSideBearing},
- {X: boundsXMin - uhm.LeftSideBearing + uhm.AdvanceWidth},
- {X: uhm.AdvanceWidth / 2, Y: boundsYMax + uvm.TopSideBearing},
- {X: uhm.AdvanceWidth / 2, Y: boundsYMax + uvm.TopSideBearing - uvm.AdvanceHeight},
- }
- if len(glyf) == 0 {
- g.addPhantomsAndScale(len(g.Points), len(g.Points), true, true)
- copy(g.phantomPoints[:], g.Points[len(g.Points)-4:])
- g.Points = g.Points[:len(g.Points)-4]
- return nil
- }
-
- // Load and hint the contours.
- if ne < 0 {
- if ne != -1 {
- // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html says that
- // "the values -2, -3, and so forth, are reserved for future use."
- return UnsupportedError("negative number of contours")
- }
- pp1x = g.font.scale(g.scale * (boundsXMin - uhm.LeftSideBearing))
- if err := g.loadCompound(recursion, uhm, i, glyf, useMyMetrics); err != nil {
- return err
- }
- } else {
- np0, ne0 := len(g.Points), len(g.Ends)
- program := g.loadSimple(glyf, ne)
- g.addPhantomsAndScale(np0, np0, true, true)
- pp1x = g.Points[len(g.Points)-4].X
- if g.hinting != font.HintingNone {
- if len(program) != 0 {
- err := g.hinter.run(
- program,
- g.Points[np0:],
- g.Unhinted[np0:],
- g.InFontUnits[np0:],
- g.Ends[ne0:],
- )
- if err != nil {
- return err
- }
- }
- // Drop the four phantom points.
- g.InFontUnits = g.InFontUnits[:len(g.InFontUnits)-4]
- g.Unhinted = g.Unhinted[:len(g.Unhinted)-4]
- }
- if useMyMetrics {
- copy(g.phantomPoints[:], g.Points[len(g.Points)-4:])
- }
- g.Points = g.Points[:len(g.Points)-4]
- if np0 != 0 {
- // The hinting program expects the []Ends values to be indexed
- // relative to the inner glyph, not the outer glyph, so we delay
- // adding np0 until after the hinting program (if any) has run.
- for i := ne0; i < len(g.Ends); i++ {
- g.Ends[i] += np0
- }
- }
- }
- if useMyMetrics && !g.metricsSet {
- g.metricsSet = true
- g.pp1x = pp1x
- }
- return nil
-}
-
-// loadOffset is the initial offset for loadSimple and loadCompound. The first
-// 10 bytes are the number of contours and the bounding box.
-const loadOffset = 10
-
-func (g *GlyphBuf) loadSimple(glyf []byte, ne int) (program []byte) {
- offset := loadOffset
- for i := 0; i < ne; i++ {
- g.Ends = append(g.Ends, 1+int(u16(glyf, offset)))
- offset += 2
- }
-
- // Note the TrueType hinting instructions.
- instrLen := int(u16(glyf, offset))
- offset += 2
- program = glyf[offset : offset+instrLen]
- offset += instrLen
-
- np0 := len(g.Points)
- np1 := np0 + int(g.Ends[len(g.Ends)-1])
-
- // Decode the flags.
- for i := np0; i < np1; {
- c := uint32(glyf[offset])
- offset++
- g.Points = append(g.Points, Point{Flags: c})
- i++
- if c&flagRepeat != 0 {
- count := glyf[offset]
- offset++
- for ; count > 0; count-- {
- g.Points = append(g.Points, Point{Flags: c})
- i++
- }
- }
- }
-
- // Decode the co-ordinates.
- var x int16
- for i := np0; i < np1; i++ {
- f := g.Points[i].Flags
- if f&flagXShortVector != 0 {
- dx := int16(glyf[offset])
- offset++
- if f&flagPositiveXShortVector == 0 {
- x -= dx
- } else {
- x += dx
- }
- } else if f&flagThisXIsSame == 0 {
- x += int16(u16(glyf, offset))
- offset += 2
- }
- g.Points[i].X = fixed.Int26_6(x)
- }
- var y int16
- for i := np0; i < np1; i++ {
- f := g.Points[i].Flags
- if f&flagYShortVector != 0 {
- dy := int16(glyf[offset])
- offset++
- if f&flagPositiveYShortVector == 0 {
- y -= dy
- } else {
- y += dy
- }
- } else if f&flagThisYIsSame == 0 {
- y += int16(u16(glyf, offset))
- offset += 2
- }
- g.Points[i].Y = fixed.Int26_6(y)
- }
-
- return program
-}
-
-func (g *GlyphBuf) loadCompound(recursion uint32, uhm HMetric, i Index,
- glyf []byte, useMyMetrics bool) error {
-
- // Flags for decoding a compound glyph. These flags are documented at
- // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html.
- const (
- flagArg1And2AreWords = 1 << iota
- flagArgsAreXYValues
- flagRoundXYToGrid
- flagWeHaveAScale
- flagUnused
- flagMoreComponents
- flagWeHaveAnXAndYScale
- flagWeHaveATwoByTwo
- flagWeHaveInstructions
- flagUseMyMetrics
- flagOverlapCompound
- )
- np0, ne0 := len(g.Points), len(g.Ends)
- offset := loadOffset
- for {
- flags := u16(glyf, offset)
- component := Index(u16(glyf, offset+2))
- dx, dy, transform, hasTransform := fixed.Int26_6(0), fixed.Int26_6(0), [4]int16{}, false
- if flags&flagArg1And2AreWords != 0 {
- dx = fixed.Int26_6(int16(u16(glyf, offset+4)))
- dy = fixed.Int26_6(int16(u16(glyf, offset+6)))
- offset += 8
- } else {
- dx = fixed.Int26_6(int16(int8(glyf[offset+4])))
- dy = fixed.Int26_6(int16(int8(glyf[offset+5])))
- offset += 6
- }
- if flags&flagArgsAreXYValues == 0 {
- return UnsupportedError("compound glyph transform vector")
- }
- if flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0 {
- hasTransform = true
- switch {
- case flags&flagWeHaveAScale != 0:
- transform[0] = int16(u16(glyf, offset+0))
- transform[3] = transform[0]
- offset += 2
- case flags&flagWeHaveAnXAndYScale != 0:
- transform[0] = int16(u16(glyf, offset+0))
- transform[3] = int16(u16(glyf, offset+2))
- offset += 4
- case flags&flagWeHaveATwoByTwo != 0:
- transform[0] = int16(u16(glyf, offset+0))
- transform[1] = int16(u16(glyf, offset+2))
- transform[2] = int16(u16(glyf, offset+4))
- transform[3] = int16(u16(glyf, offset+6))
- offset += 8
- }
- }
- savedPP := g.phantomPoints
- np0 := len(g.Points)
- componentUMM := useMyMetrics && (flags&flagUseMyMetrics != 0)
- if err := g.load(recursion+1, component, componentUMM); err != nil {
- return err
- }
- if flags&flagUseMyMetrics == 0 {
- g.phantomPoints = savedPP
- }
- if hasTransform {
- for j := np0; j < len(g.Points); j++ {
- p := &g.Points[j]
- newX := 0 +
- fixed.Int26_6((int64(p.X)*int64(transform[0])+1<<13)>>14) +
- fixed.Int26_6((int64(p.Y)*int64(transform[2])+1<<13)>>14)
- newY := 0 +
- fixed.Int26_6((int64(p.X)*int64(transform[1])+1<<13)>>14) +
- fixed.Int26_6((int64(p.Y)*int64(transform[3])+1<<13)>>14)
- p.X, p.Y = newX, newY
- }
- }
- dx = g.font.scale(g.scale * dx)
- dy = g.font.scale(g.scale * dy)
- if flags&flagRoundXYToGrid != 0 {
- dx = (dx + 32) &^ 63
- dy = (dy + 32) &^ 63
- }
- for j := np0; j < len(g.Points); j++ {
- p := &g.Points[j]
- p.X += dx
- p.Y += dy
- }
- // TODO: also adjust g.InFontUnits and g.Unhinted?
- if flags&flagMoreComponents == 0 {
- break
- }
- }
-
- instrLen := 0
- if g.hinting != font.HintingNone && offset+2 <= len(glyf) {
- instrLen = int(u16(glyf, offset))
- offset += 2
- }
-
- g.addPhantomsAndScale(np0, len(g.Points), false, instrLen > 0)
- points, ends := g.Points[np0:], g.Ends[ne0:]
- g.Points = g.Points[:len(g.Points)-4]
- for j := range points {
- points[j].Flags &^= flagTouchedX | flagTouchedY
- }
-
- if instrLen == 0 {
- if !g.metricsSet {
- copy(g.phantomPoints[:], points[len(points)-4:])
- }
- return nil
- }
-
- // Hint the compound glyph.
- program := glyf[offset : offset+instrLen]
- // Temporarily adjust the ends to be relative to this compound glyph.
- if np0 != 0 {
- for i := range ends {
- ends[i] -= np0
- }
- }
- // Hinting instructions of a composite glyph completely refer to the
- // (already) hinted subglyphs.
- g.tmp = append(g.tmp[:0], points...)
- if err := g.hinter.run(program, points, g.tmp, g.tmp, ends); err != nil {
- return err
- }
- if np0 != 0 {
- for i := range ends {
- ends[i] += np0
- }
- }
- if !g.metricsSet {
- copy(g.phantomPoints[:], points[len(points)-4:])
- }
- return nil
-}
-
-func (g *GlyphBuf) addPhantomsAndScale(np0, np1 int, simple, adjust bool) {
- // Add the four phantom points.
- g.Points = append(g.Points, g.phantomPoints[:]...)
- // Scale the points.
- if simple && g.hinting != font.HintingNone {
- g.InFontUnits = append(g.InFontUnits, g.Points[np1:]...)
- }
- for i := np1; i < len(g.Points); i++ {
- p := &g.Points[i]
- p.X = g.font.scale(g.scale * p.X)
- p.Y = g.font.scale(g.scale * p.Y)
- }
- if g.hinting == font.HintingNone {
- return
- }
- // Round the 1st phantom point to the grid, shifting all other points equally.
- // Note that "all other points" starts from np0, not np1.
- // TODO: delete this adjustment and the np0/np1 distinction, when
- // we update the compatibility tests to C Freetype 2.5.3.
- // See http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=05c786d990390a7ca18e62962641dac740bacb06
- if adjust {
- pp1x := g.Points[len(g.Points)-4].X
- if dx := ((pp1x + 32) &^ 63) - pp1x; dx != 0 {
- for i := np0; i < len(g.Points); i++ {
- g.Points[i].X += dx
- }
- }
- }
- if simple {
- g.Unhinted = append(g.Unhinted, g.Points[np1:]...)
- }
- // Round the 2nd and 4th phantom point to the grid.
- p := &g.Points[len(g.Points)-3]
- p.X = (p.X + 32) &^ 63
- p = &g.Points[len(g.Points)-1]
- p.Y = (p.Y + 32) &^ 63
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint.go
deleted file mode 100644
index 0315de511..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint.go
+++ /dev/null
@@ -1,1763 +0,0 @@
-// Copyright 2012 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-// This file implements a Truetype bytecode interpreter.
-// The opcodes are described at https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html
-
-import (
- "errors"
- "math"
-
- "golang.org/x/image/math/fixed"
-)
-
-const (
- twilightZone = 0
- glyphZone = 1
- numZone = 2
-)
-
-type pointType uint32
-
-const (
- current pointType = 0
- unhinted pointType = 1
- inFontUnits pointType = 2
- numPointType = 3
-)
-
-// callStackEntry is a bytecode call stack entry.
-type callStackEntry struct {
- program []byte
- pc int
- loopCount int32
-}
-
-// hinter implements bytecode hinting. A hinter can be re-used to hint a series
-// of glyphs from a Font.
-type hinter struct {
- stack, store []int32
-
- // functions is a map from function number to bytecode.
- functions map[int32][]byte
-
- // font and scale are the font and scale last used for this hinter.
- // Changing the font will require running the new font's fpgm bytecode.
- // Changing either will require running the font's prep bytecode.
- font *Font
- scale fixed.Int26_6
-
- // gs and defaultGS are the current and default graphics state. The
- // default graphics state is the global default graphics state after
- // the font's fpgm and prep programs have been run.
- gs, defaultGS graphicsState
-
- // points and ends are the twilight zone's points, glyph's points
- // and glyph's contour boundaries.
- points [numZone][numPointType][]Point
- ends []int
-
- // scaledCVT is the lazily initialized scaled Control Value Table.
- scaledCVTInitialized bool
- scaledCVT []fixed.Int26_6
-}
-
-// graphicsState is described at https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
-type graphicsState struct {
- // Projection vector, freedom vector and dual projection vector.
- pv, fv, dv [2]f2dot14
- // Reference points and zone pointers.
- rp, zp [3]int32
- // Control Value / Single Width Cut-In.
- controlValueCutIn, singleWidthCutIn, singleWidth fixed.Int26_6
- // Delta base / shift.
- deltaBase, deltaShift int32
- // Minimum distance.
- minDist fixed.Int26_6
- // Loop count.
- loop int32
- // Rounding policy.
- roundPeriod, roundPhase, roundThreshold fixed.Int26_6
- roundSuper45 bool
- // Auto-flip.
- autoFlip bool
-}
-
-var globalDefaultGS = graphicsState{
- pv: [2]f2dot14{0x4000, 0}, // Unit vector along the X axis.
- fv: [2]f2dot14{0x4000, 0},
- dv: [2]f2dot14{0x4000, 0},
- zp: [3]int32{1, 1, 1},
- controlValueCutIn: (17 << 6) / 16, // 17/16 as a fixed.Int26_6.
- deltaBase: 9,
- deltaShift: 3,
- minDist: 1 << 6, // 1 as a fixed.Int26_6.
- loop: 1,
- roundPeriod: 1 << 6, // 1 as a fixed.Int26_6.
- roundThreshold: 1 << 5, // 1/2 as a fixed.Int26_6.
- roundSuper45: false,
- autoFlip: true,
-}
-
-func resetTwilightPoints(f *Font, p []Point) []Point {
- if n := int(f.maxTwilightPoints) + 4; n <= cap(p) {
- p = p[:n]
- for i := range p {
- p[i] = Point{}
- }
- } else {
- p = make([]Point, n)
- }
- return p
-}
-
-func (h *hinter) init(f *Font, scale fixed.Int26_6) error {
- h.points[twilightZone][0] = resetTwilightPoints(f, h.points[twilightZone][0])
- h.points[twilightZone][1] = resetTwilightPoints(f, h.points[twilightZone][1])
- h.points[twilightZone][2] = resetTwilightPoints(f, h.points[twilightZone][2])
-
- rescale := h.scale != scale
- if h.font != f {
- h.font, rescale = f, true
- if h.functions == nil {
- h.functions = make(map[int32][]byte)
- } else {
- for k := range h.functions {
- delete(h.functions, k)
- }
- }
-
- if x := int(f.maxStackElements); x > len(h.stack) {
- x += 255
- x &^= 255
- h.stack = make([]int32, x)
- }
- if x := int(f.maxStorage); x > len(h.store) {
- x += 15
- x &^= 15
- h.store = make([]int32, x)
- }
- if len(f.fpgm) != 0 {
- if err := h.run(f.fpgm, nil, nil, nil, nil); err != nil {
- return err
- }
- }
- }
-
- if rescale {
- h.scale = scale
- h.scaledCVTInitialized = false
-
- h.defaultGS = globalDefaultGS
-
- if len(f.prep) != 0 {
- if err := h.run(f.prep, nil, nil, nil, nil); err != nil {
- return err
- }
- h.defaultGS = h.gs
- // The MS rasterizer doesn't allow the following graphics state
- // variables to be modified by the CVT program.
- h.defaultGS.pv = globalDefaultGS.pv
- h.defaultGS.fv = globalDefaultGS.fv
- h.defaultGS.dv = globalDefaultGS.dv
- h.defaultGS.rp = globalDefaultGS.rp
- h.defaultGS.zp = globalDefaultGS.zp
- h.defaultGS.loop = globalDefaultGS.loop
- }
- }
- return nil
-}
-
-func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ends []int) error {
- h.gs = h.defaultGS
- h.points[glyphZone][current] = pCurrent
- h.points[glyphZone][unhinted] = pUnhinted
- h.points[glyphZone][inFontUnits] = pInFontUnits
- h.ends = ends
-
- if len(program) > 50000 {
- return errors.New("truetype: hinting: too many instructions")
- }
- var (
- steps, pc, top int
- opcode uint8
-
- callStack [32]callStackEntry
- callStackTop int
- )
-
- for 0 <= pc && pc < len(program) {
- steps++
- if steps == 100000 {
- return errors.New("truetype: hinting: too many steps")
- }
- opcode = program[pc]
- if top < int(popCount[opcode]) {
- return errors.New("truetype: hinting: stack underflow")
- }
- switch opcode {
-
- case opSVTCA0:
- h.gs.pv = [2]f2dot14{0, 0x4000}
- h.gs.fv = [2]f2dot14{0, 0x4000}
- h.gs.dv = [2]f2dot14{0, 0x4000}
-
- case opSVTCA1:
- h.gs.pv = [2]f2dot14{0x4000, 0}
- h.gs.fv = [2]f2dot14{0x4000, 0}
- h.gs.dv = [2]f2dot14{0x4000, 0}
-
- case opSPVTCA0:
- h.gs.pv = [2]f2dot14{0, 0x4000}
- h.gs.dv = [2]f2dot14{0, 0x4000}
-
- case opSPVTCA1:
- h.gs.pv = [2]f2dot14{0x4000, 0}
- h.gs.dv = [2]f2dot14{0x4000, 0}
-
- case opSFVTCA0:
- h.gs.fv = [2]f2dot14{0, 0x4000}
-
- case opSFVTCA1:
- h.gs.fv = [2]f2dot14{0x4000, 0}
-
- case opSPVTL0, opSPVTL1, opSFVTL0, opSFVTL1:
- top -= 2
- p1 := h.point(0, current, h.stack[top+0])
- p2 := h.point(0, current, h.stack[top+1])
- if p1 == nil || p2 == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- dx := f2dot14(p1.X - p2.X)
- dy := f2dot14(p1.Y - p2.Y)
- if dx == 0 && dy == 0 {
- dx = 0x4000
- } else if opcode&1 != 0 {
- // Counter-clockwise rotation.
- dx, dy = -dy, dx
- }
- v := normalize(dx, dy)
- if opcode < opSFVTL0 {
- h.gs.pv = v
- h.gs.dv = v
- } else {
- h.gs.fv = v
- }
-
- case opSPVFS:
- top -= 2
- h.gs.pv = normalize(f2dot14(h.stack[top]), f2dot14(h.stack[top+1]))
- h.gs.dv = h.gs.pv
-
- case opSFVFS:
- top -= 2
- h.gs.fv = normalize(f2dot14(h.stack[top]), f2dot14(h.stack[top+1]))
-
- case opGPV:
- if top+1 >= len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- h.stack[top+0] = int32(h.gs.pv[0])
- h.stack[top+1] = int32(h.gs.pv[1])
- top += 2
-
- case opGFV:
- if top+1 >= len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- h.stack[top+0] = int32(h.gs.fv[0])
- h.stack[top+1] = int32(h.gs.fv[1])
- top += 2
-
- case opSFVTPV:
- h.gs.fv = h.gs.pv
-
- case opISECT:
- top -= 5
- p := h.point(2, current, h.stack[top+0])
- a0 := h.point(1, current, h.stack[top+1])
- a1 := h.point(1, current, h.stack[top+2])
- b0 := h.point(0, current, h.stack[top+3])
- b1 := h.point(0, current, h.stack[top+4])
- if p == nil || a0 == nil || a1 == nil || b0 == nil || b1 == nil {
- return errors.New("truetype: hinting: point out of range")
- }
-
- dbx := b1.X - b0.X
- dby := b1.Y - b0.Y
- dax := a1.X - a0.X
- day := a1.Y - a0.Y
- dx := b0.X - a0.X
- dy := b0.Y - a0.Y
- discriminant := mulDiv(int64(dax), int64(-dby), 0x40) +
- mulDiv(int64(day), int64(dbx), 0x40)
- dotProduct := mulDiv(int64(dax), int64(dbx), 0x40) +
- mulDiv(int64(day), int64(dby), 0x40)
- // The discriminant above is actually a cross product of vectors
- // da and db. Together with the dot product, they can be used as
- // surrogates for sine and cosine of the angle between the vectors.
- // Indeed,
- // dotproduct = |da||db|cos(angle)
- // discriminant = |da||db|sin(angle)
- // We use these equations to reject grazing intersections by
- // thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees.
- absDisc, absDotP := discriminant, dotProduct
- if absDisc < 0 {
- absDisc = -absDisc
- }
- if absDotP < 0 {
- absDotP = -absDotP
- }
- if 19*absDisc > absDotP {
- val := mulDiv(int64(dx), int64(-dby), 0x40) +
- mulDiv(int64(dy), int64(dbx), 0x40)
- rx := mulDiv(val, int64(dax), discriminant)
- ry := mulDiv(val, int64(day), discriminant)
- p.X = a0.X + fixed.Int26_6(rx)
- p.Y = a0.Y + fixed.Int26_6(ry)
- } else {
- p.X = (a0.X + a1.X + b0.X + b1.X) / 4
- p.Y = (a0.Y + a1.Y + b0.Y + b1.Y) / 4
- }
- p.Flags |= flagTouchedX | flagTouchedY
-
- case opSRP0, opSRP1, opSRP2:
- top--
- h.gs.rp[opcode-opSRP0] = h.stack[top]
-
- case opSZP0, opSZP1, opSZP2:
- top--
- h.gs.zp[opcode-opSZP0] = h.stack[top]
-
- case opSZPS:
- top--
- h.gs.zp[0] = h.stack[top]
- h.gs.zp[1] = h.stack[top]
- h.gs.zp[2] = h.stack[top]
-
- case opSLOOP:
- top--
- if h.stack[top] <= 0 {
- return errors.New("truetype: hinting: invalid data")
- }
- h.gs.loop = h.stack[top]
-
- case opRTG:
- h.gs.roundPeriod = 1 << 6
- h.gs.roundPhase = 0
- h.gs.roundThreshold = 1 << 5
- h.gs.roundSuper45 = false
-
- case opRTHG:
- h.gs.roundPeriod = 1 << 6
- h.gs.roundPhase = 1 << 5
- h.gs.roundThreshold = 1 << 5
- h.gs.roundSuper45 = false
-
- case opSMD:
- top--
- h.gs.minDist = fixed.Int26_6(h.stack[top])
-
- case opELSE:
- opcode = 1
- goto ifelse
-
- case opJMPR:
- top--
- pc += int(h.stack[top])
- continue
-
- case opSCVTCI:
- top--
- h.gs.controlValueCutIn = fixed.Int26_6(h.stack[top])
-
- case opSSWCI:
- top--
- h.gs.singleWidthCutIn = fixed.Int26_6(h.stack[top])
-
- case opSSW:
- top--
- h.gs.singleWidth = h.font.scale(h.scale * fixed.Int26_6(h.stack[top]))
-
- case opDUP:
- if top >= len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- h.stack[top] = h.stack[top-1]
- top++
-
- case opPOP:
- top--
-
- case opCLEAR:
- top = 0
-
- case opSWAP:
- h.stack[top-1], h.stack[top-2] = h.stack[top-2], h.stack[top-1]
-
- case opDEPTH:
- if top >= len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- h.stack[top] = int32(top)
- top++
-
- case opCINDEX, opMINDEX:
- x := int(h.stack[top-1])
- if x <= 0 || x >= top {
- return errors.New("truetype: hinting: invalid data")
- }
- h.stack[top-1] = h.stack[top-1-x]
- if opcode == opMINDEX {
- copy(h.stack[top-1-x:top-1], h.stack[top-x:top])
- top--
- }
-
- case opALIGNPTS:
- top -= 2
- p := h.point(1, current, h.stack[top])
- q := h.point(0, current, h.stack[top+1])
- if p == nil || q == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- d := dotProduct(fixed.Int26_6(q.X-p.X), fixed.Int26_6(q.Y-p.Y), h.gs.pv) / 2
- h.move(p, +d, true)
- h.move(q, -d, true)
-
- case opUTP:
- top--
- p := h.point(0, current, h.stack[top])
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- p.Flags &^= flagTouchedX | flagTouchedY
-
- case opLOOPCALL, opCALL:
- if callStackTop >= len(callStack) {
- return errors.New("truetype: hinting: call stack overflow")
- }
- top--
- f, ok := h.functions[h.stack[top]]
- if !ok {
- return errors.New("truetype: hinting: undefined function")
- }
- callStack[callStackTop] = callStackEntry{program, pc, 1}
- if opcode == opLOOPCALL {
- top--
- if h.stack[top] == 0 {
- break
- }
- callStack[callStackTop].loopCount = h.stack[top]
- }
- callStackTop++
- program, pc = f, 0
- continue
-
- case opFDEF:
- // Save all bytecode up until the next ENDF.
- startPC := pc + 1
- fdefloop:
- for {
- pc++
- if pc >= len(program) {
- return errors.New("truetype: hinting: unbalanced FDEF")
- }
- switch program[pc] {
- case opFDEF:
- return errors.New("truetype: hinting: nested FDEF")
- case opENDF:
- top--
- h.functions[h.stack[top]] = program[startPC : pc+1]
- break fdefloop
- default:
- var ok bool
- pc, ok = skipInstructionPayload(program, pc)
- if !ok {
- return errors.New("truetype: hinting: unbalanced FDEF")
- }
- }
- }
-
- case opENDF:
- if callStackTop == 0 {
- return errors.New("truetype: hinting: call stack underflow")
- }
- callStackTop--
- callStack[callStackTop].loopCount--
- if callStack[callStackTop].loopCount != 0 {
- callStackTop++
- pc = 0
- continue
- }
- program, pc = callStack[callStackTop].program, callStack[callStackTop].pc
-
- case opMDAP0, opMDAP1:
- top--
- i := h.stack[top]
- p := h.point(0, current, i)
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- distance := fixed.Int26_6(0)
- if opcode == opMDAP1 {
- distance = dotProduct(p.X, p.Y, h.gs.pv)
- // TODO: metrics compensation.
- distance = h.round(distance) - distance
- }
- h.move(p, distance, true)
- h.gs.rp[0] = i
- h.gs.rp[1] = i
-
- case opIUP0, opIUP1:
- iupY, mask := opcode == opIUP0, uint32(flagTouchedX)
- if iupY {
- mask = flagTouchedY
- }
- prevEnd := 0
- for _, end := range h.ends {
- for i := prevEnd; i < end; i++ {
- for i < end && h.points[glyphZone][current][i].Flags&mask == 0 {
- i++
- }
- if i == end {
- break
- }
- firstTouched, curTouched := i, i
- i++
- for ; i < end; i++ {
- if h.points[glyphZone][current][i].Flags&mask != 0 {
- h.iupInterp(iupY, curTouched+1, i-1, curTouched, i)
- curTouched = i
- }
- }
- if curTouched == firstTouched {
- h.iupShift(iupY, prevEnd, end, curTouched)
- } else {
- h.iupInterp(iupY, curTouched+1, end-1, curTouched, firstTouched)
- if firstTouched > 0 {
- h.iupInterp(iupY, prevEnd, firstTouched-1, curTouched, firstTouched)
- }
- }
- }
- prevEnd = end
- }
-
- case opSHP0, opSHP1:
- if top < int(h.gs.loop) {
- return errors.New("truetype: hinting: stack underflow")
- }
- _, _, d, ok := h.displacement(opcode&1 == 0)
- if !ok {
- return errors.New("truetype: hinting: point out of range")
- }
- for ; h.gs.loop != 0; h.gs.loop-- {
- top--
- p := h.point(2, current, h.stack[top])
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- h.move(p, d, true)
- }
- h.gs.loop = 1
-
- case opSHC0, opSHC1:
- top--
- zonePointer, i, d, ok := h.displacement(opcode&1 == 0)
- if !ok {
- return errors.New("truetype: hinting: point out of range")
- }
- if h.gs.zp[2] == 0 {
- // TODO: implement this when we have a glyph that does this.
- return errors.New("hinting: unimplemented SHC instruction")
- }
- contour := h.stack[top]
- if contour < 0 || len(ends) <= int(contour) {
- return errors.New("truetype: hinting: contour out of range")
- }
- j0, j1 := int32(0), int32(h.ends[contour])
- if contour > 0 {
- j0 = int32(h.ends[contour-1])
- }
- move := h.gs.zp[zonePointer] != h.gs.zp[2]
- for j := j0; j < j1; j++ {
- if move || j != i {
- h.move(h.point(2, current, j), d, true)
- }
- }
-
- case opSHZ0, opSHZ1:
- top--
- zonePointer, i, d, ok := h.displacement(opcode&1 == 0)
- if !ok {
- return errors.New("truetype: hinting: point out of range")
- }
-
- // As per C Freetype, SHZ doesn't move the phantom points, or mark
- // the points as touched.
- limit := int32(len(h.points[h.gs.zp[2]][current]))
- if h.gs.zp[2] == glyphZone {
- limit -= 4
- }
- for j := int32(0); j < limit; j++ {
- if i != j || h.gs.zp[zonePointer] != h.gs.zp[2] {
- h.move(h.point(2, current, j), d, false)
- }
- }
-
- case opSHPIX:
- top--
- d := fixed.Int26_6(h.stack[top])
- if top < int(h.gs.loop) {
- return errors.New("truetype: hinting: stack underflow")
- }
- for ; h.gs.loop != 0; h.gs.loop-- {
- top--
- p := h.point(2, current, h.stack[top])
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- h.move(p, d, true)
- }
- h.gs.loop = 1
-
- case opIP:
- if top < int(h.gs.loop) {
- return errors.New("truetype: hinting: stack underflow")
- }
- pointType := inFontUnits
- twilight := h.gs.zp[0] == 0 || h.gs.zp[1] == 0 || h.gs.zp[2] == 0
- if twilight {
- pointType = unhinted
- }
- p := h.point(1, pointType, h.gs.rp[2])
- oldP := h.point(0, pointType, h.gs.rp[1])
- oldRange := dotProduct(p.X-oldP.X, p.Y-oldP.Y, h.gs.dv)
-
- p = h.point(1, current, h.gs.rp[2])
- curP := h.point(0, current, h.gs.rp[1])
- curRange := dotProduct(p.X-curP.X, p.Y-curP.Y, h.gs.pv)
- for ; h.gs.loop != 0; h.gs.loop-- {
- top--
- i := h.stack[top]
- p = h.point(2, pointType, i)
- oldDist := dotProduct(p.X-oldP.X, p.Y-oldP.Y, h.gs.dv)
- p = h.point(2, current, i)
- curDist := dotProduct(p.X-curP.X, p.Y-curP.Y, h.gs.pv)
- newDist := fixed.Int26_6(0)
- if oldDist != 0 {
- if oldRange != 0 {
- newDist = fixed.Int26_6(mulDiv(int64(oldDist), int64(curRange), int64(oldRange)))
- } else {
- newDist = -oldDist
- }
- }
- h.move(p, newDist-curDist, true)
- }
- h.gs.loop = 1
-
- case opMSIRP0, opMSIRP1:
- top -= 2
- i := h.stack[top]
- distance := fixed.Int26_6(h.stack[top+1])
-
- // TODO: special case h.gs.zp[1] == 0 in C Freetype.
- ref := h.point(0, current, h.gs.rp[0])
- p := h.point(1, current, i)
- if ref == nil || p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- curDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
-
- // Set-RP0 bit.
- if opcode == opMSIRP1 {
- h.gs.rp[0] = i
- }
- h.gs.rp[1] = h.gs.rp[0]
- h.gs.rp[2] = i
-
- // Move the point.
- h.move(p, distance-curDist, true)
-
- case opALIGNRP:
- if top < int(h.gs.loop) {
- return errors.New("truetype: hinting: stack underflow")
- }
- ref := h.point(0, current, h.gs.rp[0])
- if ref == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- for ; h.gs.loop != 0; h.gs.loop-- {
- top--
- p := h.point(1, current, h.stack[top])
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- h.move(p, -dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv), true)
- }
- h.gs.loop = 1
-
- case opRTDG:
- h.gs.roundPeriod = 1 << 5
- h.gs.roundPhase = 0
- h.gs.roundThreshold = 1 << 4
- h.gs.roundSuper45 = false
-
- case opMIAP0, opMIAP1:
- top -= 2
- i := h.stack[top]
- distance := h.getScaledCVT(h.stack[top+1])
- if h.gs.zp[0] == 0 {
- p := h.point(0, unhinted, i)
- q := h.point(0, current, i)
- p.X = fixed.Int26_6((int64(distance) * int64(h.gs.fv[0])) >> 14)
- p.Y = fixed.Int26_6((int64(distance) * int64(h.gs.fv[1])) >> 14)
- *q = *p
- }
- p := h.point(0, current, i)
- oldDist := dotProduct(p.X, p.Y, h.gs.pv)
- if opcode == opMIAP1 {
- if fabs(distance-oldDist) > h.gs.controlValueCutIn {
- distance = oldDist
- }
- // TODO: metrics compensation.
- distance = h.round(distance)
- }
- h.move(p, distance-oldDist, true)
- h.gs.rp[0] = i
- h.gs.rp[1] = i
-
- case opNPUSHB:
- opcode = 0
- goto push
-
- case opNPUSHW:
- opcode = 0x80
- goto push
-
- case opWS:
- top -= 2
- i := int(h.stack[top])
- if i < 0 || len(h.store) <= i {
- return errors.New("truetype: hinting: invalid data")
- }
- h.store[i] = h.stack[top+1]
-
- case opRS:
- i := int(h.stack[top-1])
- if i < 0 || len(h.store) <= i {
- return errors.New("truetype: hinting: invalid data")
- }
- h.stack[top-1] = h.store[i]
-
- case opWCVTP:
- top -= 2
- h.setScaledCVT(h.stack[top], fixed.Int26_6(h.stack[top+1]))
-
- case opRCVT:
- h.stack[top-1] = int32(h.getScaledCVT(h.stack[top-1]))
-
- case opGC0, opGC1:
- i := h.stack[top-1]
- if opcode == opGC0 {
- p := h.point(2, current, i)
- h.stack[top-1] = int32(dotProduct(p.X, p.Y, h.gs.pv))
- } else {
- p := h.point(2, unhinted, i)
- // Using dv as per C Freetype.
- h.stack[top-1] = int32(dotProduct(p.X, p.Y, h.gs.dv))
- }
-
- case opSCFS:
- top -= 2
- i := h.stack[top]
- p := h.point(2, current, i)
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- c := dotProduct(p.X, p.Y, h.gs.pv)
- h.move(p, fixed.Int26_6(h.stack[top+1])-c, true)
- if h.gs.zp[2] != 0 {
- break
- }
- q := h.point(2, unhinted, i)
- if q == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- q.X = p.X
- q.Y = p.Y
-
- case opMD0, opMD1:
- top--
- pt, v, scale := pointType(0), [2]f2dot14{}, false
- if opcode == opMD0 {
- pt = current
- v = h.gs.pv
- } else if h.gs.zp[0] == 0 || h.gs.zp[1] == 0 {
- pt = unhinted
- v = h.gs.dv
- } else {
- pt = inFontUnits
- v = h.gs.dv
- scale = true
- }
- p := h.point(0, pt, h.stack[top-1])
- q := h.point(1, pt, h.stack[top])
- if p == nil || q == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- d := int32(dotProduct(p.X-q.X, p.Y-q.Y, v))
- if scale {
- d = int32(int64(d*int32(h.scale)) / int64(h.font.fUnitsPerEm))
- }
- h.stack[top-1] = d
-
- case opMPPEM, opMPS:
- if top >= len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- // For MPS, point size should be irrelevant; we return the PPEM.
- h.stack[top] = int32(h.scale) >> 6
- top++
-
- case opFLIPON, opFLIPOFF:
- h.gs.autoFlip = opcode == opFLIPON
-
- case opDEBUG:
- // No-op.
-
- case opLT:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] < h.stack[top])
-
- case opLTEQ:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] <= h.stack[top])
-
- case opGT:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] > h.stack[top])
-
- case opGTEQ:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] >= h.stack[top])
-
- case opEQ:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] == h.stack[top])
-
- case opNEQ:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] != h.stack[top])
-
- case opODD, opEVEN:
- i := h.round(fixed.Int26_6(h.stack[top-1])) >> 6
- h.stack[top-1] = int32(i&1) ^ int32(opcode-opODD)
-
- case opIF:
- top--
- if h.stack[top] == 0 {
- opcode = 0
- goto ifelse
- }
-
- case opEIF:
- // No-op.
-
- case opAND:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1] != 0 && h.stack[top] != 0)
-
- case opOR:
- top--
- h.stack[top-1] = bool2int32(h.stack[top-1]|h.stack[top] != 0)
-
- case opNOT:
- h.stack[top-1] = bool2int32(h.stack[top-1] == 0)
-
- case opDELTAP1:
- goto delta
-
- case opSDB:
- top--
- h.gs.deltaBase = h.stack[top]
-
- case opSDS:
- top--
- h.gs.deltaShift = h.stack[top]
-
- case opADD:
- top--
- h.stack[top-1] += h.stack[top]
-
- case opSUB:
- top--
- h.stack[top-1] -= h.stack[top]
-
- case opDIV:
- top--
- if h.stack[top] == 0 {
- return errors.New("truetype: hinting: division by zero")
- }
- h.stack[top-1] = int32(fdiv(fixed.Int26_6(h.stack[top-1]), fixed.Int26_6(h.stack[top])))
-
- case opMUL:
- top--
- h.stack[top-1] = int32(fmul(fixed.Int26_6(h.stack[top-1]), fixed.Int26_6(h.stack[top])))
-
- case opABS:
- if h.stack[top-1] < 0 {
- h.stack[top-1] = -h.stack[top-1]
- }
-
- case opNEG:
- h.stack[top-1] = -h.stack[top-1]
-
- case opFLOOR:
- h.stack[top-1] &^= 63
-
- case opCEILING:
- h.stack[top-1] += 63
- h.stack[top-1] &^= 63
-
- case opROUND00, opROUND01, opROUND10, opROUND11:
- // The four flavors of opROUND are equivalent. See the comment below on
- // opNROUND for the rationale.
- h.stack[top-1] = int32(h.round(fixed.Int26_6(h.stack[top-1])))
-
- case opNROUND00, opNROUND01, opNROUND10, opNROUND11:
- // No-op. The spec says to add one of four "compensations for the engine
- // characteristics", to cater for things like "different dot-size printers".
- // https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#engine_compensation
- // This code does not implement engine compensation, as we don't expect to
- // be used to output on dot-matrix printers.
-
- case opWCVTF:
- top -= 2
- h.setScaledCVT(h.stack[top], h.font.scale(h.scale*fixed.Int26_6(h.stack[top+1])))
-
- case opDELTAP2, opDELTAP3, opDELTAC1, opDELTAC2, opDELTAC3:
- goto delta
-
- case opSROUND, opS45ROUND:
- top--
- switch (h.stack[top] >> 6) & 0x03 {
- case 0:
- h.gs.roundPeriod = 1 << 5
- case 1, 3:
- h.gs.roundPeriod = 1 << 6
- case 2:
- h.gs.roundPeriod = 1 << 7
- }
- h.gs.roundSuper45 = opcode == opS45ROUND
- if h.gs.roundSuper45 {
- // The spec says to multiply by √2, but the C Freetype code says 1/√2.
- // We go with 1/√2.
- h.gs.roundPeriod *= 46341
- h.gs.roundPeriod /= 65536
- }
- h.gs.roundPhase = h.gs.roundPeriod * fixed.Int26_6((h.stack[top]>>4)&0x03) / 4
- if x := h.stack[top] & 0x0f; x != 0 {
- h.gs.roundThreshold = h.gs.roundPeriod * fixed.Int26_6(x-4) / 8
- } else {
- h.gs.roundThreshold = h.gs.roundPeriod - 1
- }
-
- case opJROT:
- top -= 2
- if h.stack[top+1] != 0 {
- pc += int(h.stack[top])
- continue
- }
-
- case opJROF:
- top -= 2
- if h.stack[top+1] == 0 {
- pc += int(h.stack[top])
- continue
- }
-
- case opROFF:
- h.gs.roundPeriod = 0
- h.gs.roundPhase = 0
- h.gs.roundThreshold = 0
- h.gs.roundSuper45 = false
-
- case opRUTG:
- h.gs.roundPeriod = 1 << 6
- h.gs.roundPhase = 0
- h.gs.roundThreshold = 1<<6 - 1
- h.gs.roundSuper45 = false
-
- case opRDTG:
- h.gs.roundPeriod = 1 << 6
- h.gs.roundPhase = 0
- h.gs.roundThreshold = 0
- h.gs.roundSuper45 = false
-
- case opSANGW, opAA:
- // These ops are "anachronistic" and no longer used.
- top--
-
- case opFLIPPT:
- if top < int(h.gs.loop) {
- return errors.New("truetype: hinting: stack underflow")
- }
- points := h.points[glyphZone][current]
- for ; h.gs.loop != 0; h.gs.loop-- {
- top--
- i := h.stack[top]
- if i < 0 || len(points) <= int(i) {
- return errors.New("truetype: hinting: point out of range")
- }
- points[i].Flags ^= flagOnCurve
- }
- h.gs.loop = 1
-
- case opFLIPRGON, opFLIPRGOFF:
- top -= 2
- i, j, points := h.stack[top], h.stack[top+1], h.points[glyphZone][current]
- if i < 0 || len(points) <= int(i) || j < 0 || len(points) <= int(j) {
- return errors.New("truetype: hinting: point out of range")
- }
- for ; i <= j; i++ {
- if opcode == opFLIPRGON {
- points[i].Flags |= flagOnCurve
- } else {
- points[i].Flags &^= flagOnCurve
- }
- }
-
- case opSCANCTRL:
- // We do not support dropout control, as we always rasterize grayscale glyphs.
- top--
-
- case opSDPVTL0, opSDPVTL1:
- top -= 2
- for i := 0; i < 2; i++ {
- pt := unhinted
- if i != 0 {
- pt = current
- }
- p := h.point(1, pt, h.stack[top])
- q := h.point(2, pt, h.stack[top+1])
- if p == nil || q == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- dx := f2dot14(p.X - q.X)
- dy := f2dot14(p.Y - q.Y)
- if dx == 0 && dy == 0 {
- dx = 0x4000
- } else if opcode&1 != 0 {
- // Counter-clockwise rotation.
- dx, dy = -dy, dx
- }
- if i == 0 {
- h.gs.dv = normalize(dx, dy)
- } else {
- h.gs.pv = normalize(dx, dy)
- }
- }
-
- case opGETINFO:
- res := int32(0)
- if h.stack[top-1]&(1<<0) != 0 {
- // Set the engine version. We hard-code this to 35, the same as
- // the C freetype code, which says that "Version~35 corresponds
- // to MS rasterizer v.1.7 as used e.g. in Windows~98".
- res |= 35
- }
- if h.stack[top-1]&(1<<5) != 0 {
- // Set that we support grayscale.
- res |= 1 << 12
- }
- // We set no other bits, as we do not support rotated or stretched glyphs.
- h.stack[top-1] = res
-
- case opIDEF:
- // IDEF is for ancient versions of the bytecode interpreter, and is no longer used.
- return errors.New("truetype: hinting: unsupported IDEF instruction")
-
- case opROLL:
- h.stack[top-1], h.stack[top-3], h.stack[top-2] =
- h.stack[top-3], h.stack[top-2], h.stack[top-1]
-
- case opMAX:
- top--
- if h.stack[top-1] < h.stack[top] {
- h.stack[top-1] = h.stack[top]
- }
-
- case opMIN:
- top--
- if h.stack[top-1] > h.stack[top] {
- h.stack[top-1] = h.stack[top]
- }
-
- case opSCANTYPE:
- // We do not support dropout control, as we always rasterize grayscale glyphs.
- top--
-
- case opINSTCTRL:
- // TODO: support instruction execution control? It seems rare, and even when
- // nominally used (e.g. Source Sans Pro), it seems conditional on extreme or
- // unusual rasterization conditions. For example, the code snippet at
- // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html#INSTCTRL
- // uses INSTCTRL when grid-fitting a rotated or stretched glyph, but
- // freetype-go does not support rotated or stretched glyphs.
- top -= 2
-
- default:
- if opcode < opPUSHB000 {
- return errors.New("truetype: hinting: unrecognized instruction")
- }
-
- if opcode < opMDRP00000 {
- // PUSHxxxx opcode.
-
- if opcode < opPUSHW000 {
- opcode -= opPUSHB000 - 1
- } else {
- opcode -= opPUSHW000 - 1 - 0x80
- }
- goto push
- }
-
- if opcode < opMIRP00000 {
- // MDRPxxxxx opcode.
-
- top--
- i := h.stack[top]
- ref := h.point(0, current, h.gs.rp[0])
- p := h.point(1, current, i)
- if ref == nil || p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
-
- oldDist := fixed.Int26_6(0)
- if h.gs.zp[0] == 0 || h.gs.zp[1] == 0 {
- p0 := h.point(1, unhinted, i)
- p1 := h.point(0, unhinted, h.gs.rp[0])
- oldDist = dotProduct(p0.X-p1.X, p0.Y-p1.Y, h.gs.dv)
- } else {
- p0 := h.point(1, inFontUnits, i)
- p1 := h.point(0, inFontUnits, h.gs.rp[0])
- oldDist = dotProduct(p0.X-p1.X, p0.Y-p1.Y, h.gs.dv)
- oldDist = h.font.scale(h.scale * oldDist)
- }
-
- // Single-width cut-in test.
- if x := fabs(oldDist - h.gs.singleWidth); x < h.gs.singleWidthCutIn {
- if oldDist >= 0 {
- oldDist = +h.gs.singleWidth
- } else {
- oldDist = -h.gs.singleWidth
- }
- }
-
- // Rounding bit.
- // TODO: metrics compensation.
- distance := oldDist
- if opcode&0x04 != 0 {
- distance = h.round(oldDist)
- }
-
- // Minimum distance bit.
- if opcode&0x08 != 0 {
- if oldDist >= 0 {
- if distance < h.gs.minDist {
- distance = h.gs.minDist
- }
- } else {
- if distance > -h.gs.minDist {
- distance = -h.gs.minDist
- }
- }
- }
-
- // Set-RP0 bit.
- h.gs.rp[1] = h.gs.rp[0]
- h.gs.rp[2] = i
- if opcode&0x10 != 0 {
- h.gs.rp[0] = i
- }
-
- // Move the point.
- oldDist = dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
- h.move(p, distance-oldDist, true)
-
- } else {
- // MIRPxxxxx opcode.
-
- top -= 2
- i := h.stack[top]
- cvtDist := h.getScaledCVT(h.stack[top+1])
- if fabs(cvtDist-h.gs.singleWidth) < h.gs.singleWidthCutIn {
- if cvtDist >= 0 {
- cvtDist = +h.gs.singleWidth
- } else {
- cvtDist = -h.gs.singleWidth
- }
- }
-
- if h.gs.zp[1] == 0 {
- // TODO: implement once we have a .ttf file that triggers
- // this, so that we can step through C's freetype.
- return errors.New("truetype: hinting: unimplemented twilight point adjustment")
- }
-
- ref := h.point(0, unhinted, h.gs.rp[0])
- p := h.point(1, unhinted, i)
- if ref == nil || p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- oldDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.dv)
-
- ref = h.point(0, current, h.gs.rp[0])
- p = h.point(1, current, i)
- if ref == nil || p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- curDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
-
- if h.gs.autoFlip && oldDist^cvtDist < 0 {
- cvtDist = -cvtDist
- }
-
- // Rounding bit.
- // TODO: metrics compensation.
- distance := cvtDist
- if opcode&0x04 != 0 {
- // The CVT value is only used if close enough to oldDist.
- if (h.gs.zp[0] == h.gs.zp[1]) &&
- (fabs(cvtDist-oldDist) > h.gs.controlValueCutIn) {
-
- distance = oldDist
- }
- distance = h.round(distance)
- }
-
- // Minimum distance bit.
- if opcode&0x08 != 0 {
- if oldDist >= 0 {
- if distance < h.gs.minDist {
- distance = h.gs.minDist
- }
- } else {
- if distance > -h.gs.minDist {
- distance = -h.gs.minDist
- }
- }
- }
-
- // Set-RP0 bit.
- h.gs.rp[1] = h.gs.rp[0]
- h.gs.rp[2] = i
- if opcode&0x10 != 0 {
- h.gs.rp[0] = i
- }
-
- // Move the point.
- h.move(p, distance-curDist, true)
- }
- }
- pc++
- continue
-
- ifelse:
- // Skip past bytecode until the next ELSE (if opcode == 0) or the
- // next EIF (for all opcodes). Opcode == 0 means that we have come
- // from an IF. Opcode == 1 means that we have come from an ELSE.
- {
- ifelseloop:
- for depth := 0; ; {
- pc++
- if pc >= len(program) {
- return errors.New("truetype: hinting: unbalanced IF or ELSE")
- }
- switch program[pc] {
- case opIF:
- depth++
- case opELSE:
- if depth == 0 && opcode == 0 {
- break ifelseloop
- }
- case opEIF:
- depth--
- if depth < 0 {
- break ifelseloop
- }
- default:
- var ok bool
- pc, ok = skipInstructionPayload(program, pc)
- if !ok {
- return errors.New("truetype: hinting: unbalanced IF or ELSE")
- }
- }
- }
- pc++
- continue
- }
-
- push:
- // Push n elements from the program to the stack, where n is the low 7 bits of
- // opcode. If the low 7 bits are zero, then n is the next byte from the program.
- // The high bit being 0 means that the elements are zero-extended bytes.
- // The high bit being 1 means that the elements are sign-extended words.
- {
- width := 1
- if opcode&0x80 != 0 {
- opcode &^= 0x80
- width = 2
- }
- if opcode == 0 {
- pc++
- if pc >= len(program) {
- return errors.New("truetype: hinting: insufficient data")
- }
- opcode = program[pc]
- }
- pc++
- if top+int(opcode) > len(h.stack) {
- return errors.New("truetype: hinting: stack overflow")
- }
- if pc+width*int(opcode) > len(program) {
- return errors.New("truetype: hinting: insufficient data")
- }
- for ; opcode > 0; opcode-- {
- if width == 1 {
- h.stack[top] = int32(program[pc])
- } else {
- h.stack[top] = int32(int8(program[pc]))<<8 | int32(program[pc+1])
- }
- top++
- pc += width
- }
- continue
- }
-
- delta:
- {
- if opcode >= opDELTAC1 && !h.scaledCVTInitialized {
- h.initializeScaledCVT()
- }
- top--
- n := h.stack[top]
- if int32(top) < 2*n {
- return errors.New("truetype: hinting: stack underflow")
- }
- for ; n > 0; n-- {
- top -= 2
- b := h.stack[top]
- c := (b & 0xf0) >> 4
- switch opcode {
- case opDELTAP2, opDELTAC2:
- c += 16
- case opDELTAP3, opDELTAC3:
- c += 32
- }
- c += h.gs.deltaBase
- if ppem := (int32(h.scale) + 1<<5) >> 6; ppem != c {
- continue
- }
- b = (b & 0x0f) - 8
- if b >= 0 {
- b++
- }
- b = b * 64 / (1 << uint32(h.gs.deltaShift))
- if opcode >= opDELTAC1 {
- a := h.stack[top+1]
- if a < 0 || len(h.scaledCVT) <= int(a) {
- return errors.New("truetype: hinting: index out of range")
- }
- h.scaledCVT[a] += fixed.Int26_6(b)
- } else {
- p := h.point(0, current, h.stack[top+1])
- if p == nil {
- return errors.New("truetype: hinting: point out of range")
- }
- h.move(p, fixed.Int26_6(b), true)
- }
- }
- pc++
- continue
- }
- }
- return nil
-}
-
-func (h *hinter) initializeScaledCVT() {
- h.scaledCVTInitialized = true
- if n := len(h.font.cvt) / 2; n <= cap(h.scaledCVT) {
- h.scaledCVT = h.scaledCVT[:n]
- } else {
- if n < 32 {
- n = 32
- }
- h.scaledCVT = make([]fixed.Int26_6, len(h.font.cvt)/2, n)
- }
- for i := range h.scaledCVT {
- unscaled := uint16(h.font.cvt[2*i])<<8 | uint16(h.font.cvt[2*i+1])
- h.scaledCVT[i] = h.font.scale(h.scale * fixed.Int26_6(int16(unscaled)))
- }
-}
-
-// getScaledCVT returns the scaled value from the font's Control Value Table.
-func (h *hinter) getScaledCVT(i int32) fixed.Int26_6 {
- if !h.scaledCVTInitialized {
- h.initializeScaledCVT()
- }
- if i < 0 || len(h.scaledCVT) <= int(i) {
- return 0
- }
- return h.scaledCVT[i]
-}
-
-// setScaledCVT overrides the scaled value from the font's Control Value Table.
-func (h *hinter) setScaledCVT(i int32, v fixed.Int26_6) {
- if !h.scaledCVTInitialized {
- h.initializeScaledCVT()
- }
- if i < 0 || len(h.scaledCVT) <= int(i) {
- return
- }
- h.scaledCVT[i] = v
-}
-
-func (h *hinter) point(zonePointer uint32, pt pointType, i int32) *Point {
- points := h.points[h.gs.zp[zonePointer]][pt]
- if i < 0 || len(points) <= int(i) {
- return nil
- }
- return &points[i]
-}
-
-func (h *hinter) move(p *Point, distance fixed.Int26_6, touch bool) {
- fvx := int64(h.gs.fv[0])
- pvx := int64(h.gs.pv[0])
- if fvx == 0x4000 && pvx == 0x4000 {
- p.X += fixed.Int26_6(distance)
- if touch {
- p.Flags |= flagTouchedX
- }
- return
- }
-
- fvy := int64(h.gs.fv[1])
- pvy := int64(h.gs.pv[1])
- if fvy == 0x4000 && pvy == 0x4000 {
- p.Y += fixed.Int26_6(distance)
- if touch {
- p.Flags |= flagTouchedY
- }
- return
- }
-
- fvDotPv := (fvx*pvx + fvy*pvy) >> 14
-
- if fvx != 0 {
- p.X += fixed.Int26_6(mulDiv(fvx, int64(distance), fvDotPv))
- if touch {
- p.Flags |= flagTouchedX
- }
- }
-
- if fvy != 0 {
- p.Y += fixed.Int26_6(mulDiv(fvy, int64(distance), fvDotPv))
- if touch {
- p.Flags |= flagTouchedY
- }
- }
-}
-
-func (h *hinter) iupInterp(interpY bool, p1, p2, ref1, ref2 int) {
- if p1 > p2 {
- return
- }
- if ref1 >= len(h.points[glyphZone][current]) ||
- ref2 >= len(h.points[glyphZone][current]) {
- return
- }
-
- var ifu1, ifu2 fixed.Int26_6
- if interpY {
- ifu1 = h.points[glyphZone][inFontUnits][ref1].Y
- ifu2 = h.points[glyphZone][inFontUnits][ref2].Y
- } else {
- ifu1 = h.points[glyphZone][inFontUnits][ref1].X
- ifu2 = h.points[glyphZone][inFontUnits][ref2].X
- }
- if ifu1 > ifu2 {
- ifu1, ifu2 = ifu2, ifu1
- ref1, ref2 = ref2, ref1
- }
-
- var unh1, unh2, delta1, delta2 fixed.Int26_6
- if interpY {
- unh1 = h.points[glyphZone][unhinted][ref1].Y
- unh2 = h.points[glyphZone][unhinted][ref2].Y
- delta1 = h.points[glyphZone][current][ref1].Y - unh1
- delta2 = h.points[glyphZone][current][ref2].Y - unh2
- } else {
- unh1 = h.points[glyphZone][unhinted][ref1].X
- unh2 = h.points[glyphZone][unhinted][ref2].X
- delta1 = h.points[glyphZone][current][ref1].X - unh1
- delta2 = h.points[glyphZone][current][ref2].X - unh2
- }
-
- var xy, ifuXY fixed.Int26_6
- if ifu1 == ifu2 {
- for i := p1; i <= p2; i++ {
- if interpY {
- xy = h.points[glyphZone][unhinted][i].Y
- } else {
- xy = h.points[glyphZone][unhinted][i].X
- }
-
- if xy <= unh1 {
- xy += delta1
- } else {
- xy += delta2
- }
-
- if interpY {
- h.points[glyphZone][current][i].Y = xy
- } else {
- h.points[glyphZone][current][i].X = xy
- }
- }
- return
- }
-
- scale, scaleOK := int64(0), false
- for i := p1; i <= p2; i++ {
- if interpY {
- xy = h.points[glyphZone][unhinted][i].Y
- ifuXY = h.points[glyphZone][inFontUnits][i].Y
- } else {
- xy = h.points[glyphZone][unhinted][i].X
- ifuXY = h.points[glyphZone][inFontUnits][i].X
- }
-
- if xy <= unh1 {
- xy += delta1
- } else if xy >= unh2 {
- xy += delta2
- } else {
- if !scaleOK {
- scaleOK = true
- scale = mulDiv(int64(unh2+delta2-unh1-delta1), 0x10000, int64(ifu2-ifu1))
- }
- numer := int64(ifuXY-ifu1) * scale
- if numer >= 0 {
- numer += 0x8000
- } else {
- numer -= 0x8000
- }
- xy = unh1 + delta1 + fixed.Int26_6(numer/0x10000)
- }
-
- if interpY {
- h.points[glyphZone][current][i].Y = xy
- } else {
- h.points[glyphZone][current][i].X = xy
- }
- }
-}
-
-func (h *hinter) iupShift(interpY bool, p1, p2, p int) {
- var delta fixed.Int26_6
- if interpY {
- delta = h.points[glyphZone][current][p].Y - h.points[glyphZone][unhinted][p].Y
- } else {
- delta = h.points[glyphZone][current][p].X - h.points[glyphZone][unhinted][p].X
- }
- if delta == 0 {
- return
- }
- for i := p1; i < p2; i++ {
- if i == p {
- continue
- }
- if interpY {
- h.points[glyphZone][current][i].Y += delta
- } else {
- h.points[glyphZone][current][i].X += delta
- }
- }
-}
-
-func (h *hinter) displacement(useZP1 bool) (zonePointer uint32, i int32, d fixed.Int26_6, ok bool) {
- zonePointer, i = uint32(0), h.gs.rp[1]
- if useZP1 {
- zonePointer, i = 1, h.gs.rp[2]
- }
- p := h.point(zonePointer, current, i)
- q := h.point(zonePointer, unhinted, i)
- if p == nil || q == nil {
- return 0, 0, 0, false
- }
- d = dotProduct(p.X-q.X, p.Y-q.Y, h.gs.pv)
- return zonePointer, i, d, true
-}
-
-// skipInstructionPayload increments pc by the extra data that follows a
-// variable length PUSHB or PUSHW instruction.
-func skipInstructionPayload(program []byte, pc int) (newPC int, ok bool) {
- switch program[pc] {
- case opNPUSHB:
- pc++
- if pc >= len(program) {
- return 0, false
- }
- pc += int(program[pc])
- case opNPUSHW:
- pc++
- if pc >= len(program) {
- return 0, false
- }
- pc += 2 * int(program[pc])
- case opPUSHB000, opPUSHB001, opPUSHB010, opPUSHB011,
- opPUSHB100, opPUSHB101, opPUSHB110, opPUSHB111:
- pc += int(program[pc] - (opPUSHB000 - 1))
- case opPUSHW000, opPUSHW001, opPUSHW010, opPUSHW011,
- opPUSHW100, opPUSHW101, opPUSHW110, opPUSHW111:
- pc += 2 * int(program[pc]-(opPUSHW000-1))
- }
- return pc, true
-}
-
-// f2dot14 is a 2.14 fixed point number.
-type f2dot14 int16
-
-func normalize(x, y f2dot14) [2]f2dot14 {
- fx, fy := float64(x), float64(y)
- l := 0x4000 / math.Hypot(fx, fy)
- fx *= l
- if fx >= 0 {
- fx += 0.5
- } else {
- fx -= 0.5
- }
- fy *= l
- if fy >= 0 {
- fy += 0.5
- } else {
- fy -= 0.5
- }
- return [2]f2dot14{f2dot14(fx), f2dot14(fy)}
-}
-
-// fabs returns abs(x) in 26.6 fixed point arithmetic.
-func fabs(x fixed.Int26_6) fixed.Int26_6 {
- if x < 0 {
- return -x
- }
- return x
-}
-
-// fdiv returns x/y in 26.6 fixed point arithmetic.
-func fdiv(x, y fixed.Int26_6) fixed.Int26_6 {
- return fixed.Int26_6((int64(x) << 6) / int64(y))
-}
-
-// fmul returns x*y in 26.6 fixed point arithmetic.
-func fmul(x, y fixed.Int26_6) fixed.Int26_6 {
- return fixed.Int26_6((int64(x)*int64(y) + 1<<5) >> 6)
-}
-
-// dotProduct returns the dot product of [x, y] and q. It is almost the same as
-// px := int64(x)
-// py := int64(y)
-// qx := int64(q[0])
-// qy := int64(q[1])
-// return fixed.Int26_6((px*qx + py*qy + 1<<13) >> 14)
-// except that the computation is done with 32-bit integers to produce exactly
-// the same rounding behavior as C Freetype.
-func dotProduct(x, y fixed.Int26_6, q [2]f2dot14) fixed.Int26_6 {
- // Compute x*q[0] as 64-bit value.
- l := uint32((int32(x) & 0xFFFF) * int32(q[0]))
- m := (int32(x) >> 16) * int32(q[0])
-
- lo1 := l + (uint32(m) << 16)
- hi1 := (m >> 16) + (int32(l) >> 31) + bool2int32(lo1 < l)
-
- // Compute y*q[1] as 64-bit value.
- l = uint32((int32(y) & 0xFFFF) * int32(q[1]))
- m = (int32(y) >> 16) * int32(q[1])
-
- lo2 := l + (uint32(m) << 16)
- hi2 := (m >> 16) + (int32(l) >> 31) + bool2int32(lo2 < l)
-
- // Add them.
- lo := lo1 + lo2
- hi := hi1 + hi2 + bool2int32(lo < lo1)
-
- // Divide the result by 2^14 with rounding.
- s := hi >> 31
- l = lo + uint32(s)
- hi += s + bool2int32(l < lo)
- lo = l
-
- l = lo + 0x2000
- hi += bool2int32(l < lo)
-
- return fixed.Int26_6((uint32(hi) << 18) | (l >> 14))
-}
-
-// mulDiv returns x*y/z, rounded to the nearest integer.
-func mulDiv(x, y, z int64) int64 {
- xy := x * y
- if z < 0 {
- xy, z = -xy, -z
- }
- if xy >= 0 {
- xy += z / 2
- } else {
- xy -= z / 2
- }
- return xy / z
-}
-
-// round rounds the given number. The rounding algorithm is described at
-// https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
-func (h *hinter) round(x fixed.Int26_6) fixed.Int26_6 {
- if h.gs.roundPeriod == 0 {
- // Rounding is off.
- return x
- }
- if x >= 0 {
- ret := x - h.gs.roundPhase + h.gs.roundThreshold
- if h.gs.roundSuper45 {
- ret /= h.gs.roundPeriod
- ret *= h.gs.roundPeriod
- } else {
- ret &= -h.gs.roundPeriod
- }
- if x != 0 && ret < 0 {
- ret = 0
- }
- return ret + h.gs.roundPhase
- }
- ret := -x - h.gs.roundPhase + h.gs.roundThreshold
- if h.gs.roundSuper45 {
- ret /= h.gs.roundPeriod
- ret *= h.gs.roundPeriod
- } else {
- ret &= -h.gs.roundPeriod
- }
- if ret < 0 {
- ret = 0
- }
- return -ret - h.gs.roundPhase
-}
-
-func bool2int32(b bool) int32 {
- if b {
- return 1
- }
- return 0
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/opcodes.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/opcodes.go
deleted file mode 100644
index 1880e1e63..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/opcodes.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2012 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-// The Truetype opcodes are summarized at
-// https://developer.apple.com/fonts/TTRefMan/RM07/appendixA.html
-
-const (
- opSVTCA0 = 0x00 // Set freedom and projection Vectors To Coordinate Axis
- opSVTCA1 = 0x01 // .
- opSPVTCA0 = 0x02 // Set Projection Vector To Coordinate Axis
- opSPVTCA1 = 0x03 // .
- opSFVTCA0 = 0x04 // Set Freedom Vector to Coordinate Axis
- opSFVTCA1 = 0x05 // .
- opSPVTL0 = 0x06 // Set Projection Vector To Line
- opSPVTL1 = 0x07 // .
- opSFVTL0 = 0x08 // Set Freedom Vector To Line
- opSFVTL1 = 0x09 // .
- opSPVFS = 0x0a // Set Projection Vector From Stack
- opSFVFS = 0x0b // Set Freedom Vector From Stack
- opGPV = 0x0c // Get Projection Vector
- opGFV = 0x0d // Get Freedom Vector
- opSFVTPV = 0x0e // Set Freedom Vector To Projection Vector
- opISECT = 0x0f // moves point p to the InterSECTion of two lines
- opSRP0 = 0x10 // Set Reference Point 0
- opSRP1 = 0x11 // Set Reference Point 1
- opSRP2 = 0x12 // Set Reference Point 2
- opSZP0 = 0x13 // Set Zone Pointer 0
- opSZP1 = 0x14 // Set Zone Pointer 1
- opSZP2 = 0x15 // Set Zone Pointer 2
- opSZPS = 0x16 // Set Zone PointerS
- opSLOOP = 0x17 // Set LOOP variable
- opRTG = 0x18 // Round To Grid
- opRTHG = 0x19 // Round To Half Grid
- opSMD = 0x1a // Set Minimum Distance
- opELSE = 0x1b // ELSE clause
- opJMPR = 0x1c // JuMP Relative
- opSCVTCI = 0x1d // Set Control Value Table Cut-In
- opSSWCI = 0x1e // Set Single Width Cut-In
- opSSW = 0x1f // Set Single Width
- opDUP = 0x20 // DUPlicate top stack element
- opPOP = 0x21 // POP top stack element
- opCLEAR = 0x22 // CLEAR the stack
- opSWAP = 0x23 // SWAP the top two elements on the stack
- opDEPTH = 0x24 // DEPTH of the stack
- opCINDEX = 0x25 // Copy the INDEXed element to the top of the stack
- opMINDEX = 0x26 // Move the INDEXed element to the top of the stack
- opALIGNPTS = 0x27 // ALIGN PoinTS
- op_0x28 = 0x28 // deprecated
- opUTP = 0x29 // UnTouch Point
- opLOOPCALL = 0x2a // LOOP and CALL function
- opCALL = 0x2b // CALL function
- opFDEF = 0x2c // Function DEFinition
- opENDF = 0x2d // END Function definition
- opMDAP0 = 0x2e // Move Direct Absolute Point
- opMDAP1 = 0x2f // .
- opIUP0 = 0x30 // Interpolate Untouched Points through the outline
- opIUP1 = 0x31 // .
- opSHP0 = 0x32 // SHift Point using reference point
- opSHP1 = 0x33 // .
- opSHC0 = 0x34 // SHift Contour using reference point
- opSHC1 = 0x35 // .
- opSHZ0 = 0x36 // SHift Zone using reference point
- opSHZ1 = 0x37 // .
- opSHPIX = 0x38 // SHift point by a PIXel amount
- opIP = 0x39 // Interpolate Point
- opMSIRP0 = 0x3a // Move Stack Indirect Relative Point
- opMSIRP1 = 0x3b // .
- opALIGNRP = 0x3c // ALIGN to Reference Point
- opRTDG = 0x3d // Round To Double Grid
- opMIAP0 = 0x3e // Move Indirect Absolute Point
- opMIAP1 = 0x3f // .
- opNPUSHB = 0x40 // PUSH N Bytes
- opNPUSHW = 0x41 // PUSH N Words
- opWS = 0x42 // Write Store
- opRS = 0x43 // Read Store
- opWCVTP = 0x44 // Write Control Value Table in Pixel units
- opRCVT = 0x45 // Read Control Value Table entry
- opGC0 = 0x46 // Get Coordinate projected onto the projection vector
- opGC1 = 0x47 // .
- opSCFS = 0x48 // Sets Coordinate From the Stack using projection vector and freedom vector
- opMD0 = 0x49 // Measure Distance
- opMD1 = 0x4a // .
- opMPPEM = 0x4b // Measure Pixels Per EM
- opMPS = 0x4c // Measure Point Size
- opFLIPON = 0x4d // set the auto FLIP Boolean to ON
- opFLIPOFF = 0x4e // set the auto FLIP Boolean to OFF
- opDEBUG = 0x4f // DEBUG call
- opLT = 0x50 // Less Than
- opLTEQ = 0x51 // Less Than or EQual
- opGT = 0x52 // Greater Than
- opGTEQ = 0x53 // Greater Than or EQual
- opEQ = 0x54 // EQual
- opNEQ = 0x55 // Not EQual
- opODD = 0x56 // ODD
- opEVEN = 0x57 // EVEN
- opIF = 0x58 // IF test
- opEIF = 0x59 // End IF
- opAND = 0x5a // logical AND
- opOR = 0x5b // logical OR
- opNOT = 0x5c // logical NOT
- opDELTAP1 = 0x5d // DELTA exception P1
- opSDB = 0x5e // Set Delta Base in the graphics state
- opSDS = 0x5f // Set Delta Shift in the graphics state
- opADD = 0x60 // ADD
- opSUB = 0x61 // SUBtract
- opDIV = 0x62 // DIVide
- opMUL = 0x63 // MULtiply
- opABS = 0x64 // ABSolute value
- opNEG = 0x65 // NEGate
- opFLOOR = 0x66 // FLOOR
- opCEILING = 0x67 // CEILING
- opROUND00 = 0x68 // ROUND value
- opROUND01 = 0x69 // .
- opROUND10 = 0x6a // .
- opROUND11 = 0x6b // .
- opNROUND00 = 0x6c // No ROUNDing of value
- opNROUND01 = 0x6d // .
- opNROUND10 = 0x6e // .
- opNROUND11 = 0x6f // .
- opWCVTF = 0x70 // Write Control Value Table in Funits
- opDELTAP2 = 0x71 // DELTA exception P2
- opDELTAP3 = 0x72 // DELTA exception P3
- opDELTAC1 = 0x73 // DELTA exception C1
- opDELTAC2 = 0x74 // DELTA exception C2
- opDELTAC3 = 0x75 // DELTA exception C3
- opSROUND = 0x76 // Super ROUND
- opS45ROUND = 0x77 // Super ROUND 45 degrees
- opJROT = 0x78 // Jump Relative On True
- opJROF = 0x79 // Jump Relative On False
- opROFF = 0x7a // Round OFF
- op_0x7b = 0x7b // deprecated
- opRUTG = 0x7c // Round Up To Grid
- opRDTG = 0x7d // Round Down To Grid
- opSANGW = 0x7e // Set ANGle Weight
- opAA = 0x7f // Adjust Angle
- opFLIPPT = 0x80 // FLIP PoinT
- opFLIPRGON = 0x81 // FLIP RanGe ON
- opFLIPRGOFF = 0x82 // FLIP RanGe OFF
- op_0x83 = 0x83 // deprecated
- op_0x84 = 0x84 // deprecated
- opSCANCTRL = 0x85 // SCAN conversion ConTRoL
- opSDPVTL0 = 0x86 // Set Dual Projection Vector To Line
- opSDPVTL1 = 0x87 // .
- opGETINFO = 0x88 // GET INFOrmation
- opIDEF = 0x89 // Instruction DEFinition
- opROLL = 0x8a // ROLL the top three stack elements
- opMAX = 0x8b // MAXimum of top two stack elements
- opMIN = 0x8c // MINimum of top two stack elements
- opSCANTYPE = 0x8d // SCANTYPE
- opINSTCTRL = 0x8e // INSTRuction execution ConTRoL
- op_0x8f = 0x8f
- op_0x90 = 0x90
- op_0x91 = 0x91
- op_0x92 = 0x92
- op_0x93 = 0x93
- op_0x94 = 0x94
- op_0x95 = 0x95
- op_0x96 = 0x96
- op_0x97 = 0x97
- op_0x98 = 0x98
- op_0x99 = 0x99
- op_0x9a = 0x9a
- op_0x9b = 0x9b
- op_0x9c = 0x9c
- op_0x9d = 0x9d
- op_0x9e = 0x9e
- op_0x9f = 0x9f
- op_0xa0 = 0xa0
- op_0xa1 = 0xa1
- op_0xa2 = 0xa2
- op_0xa3 = 0xa3
- op_0xa4 = 0xa4
- op_0xa5 = 0xa5
- op_0xa6 = 0xa6
- op_0xa7 = 0xa7
- op_0xa8 = 0xa8
- op_0xa9 = 0xa9
- op_0xaa = 0xaa
- op_0xab = 0xab
- op_0xac = 0xac
- op_0xad = 0xad
- op_0xae = 0xae
- op_0xaf = 0xaf
- opPUSHB000 = 0xb0 // PUSH Bytes
- opPUSHB001 = 0xb1 // .
- opPUSHB010 = 0xb2 // .
- opPUSHB011 = 0xb3 // .
- opPUSHB100 = 0xb4 // .
- opPUSHB101 = 0xb5 // .
- opPUSHB110 = 0xb6 // .
- opPUSHB111 = 0xb7 // .
- opPUSHW000 = 0xb8 // PUSH Words
- opPUSHW001 = 0xb9 // .
- opPUSHW010 = 0xba // .
- opPUSHW011 = 0xbb // .
- opPUSHW100 = 0xbc // .
- opPUSHW101 = 0xbd // .
- opPUSHW110 = 0xbe // .
- opPUSHW111 = 0xbf // .
- opMDRP00000 = 0xc0 // Move Direct Relative Point
- opMDRP00001 = 0xc1 // .
- opMDRP00010 = 0xc2 // .
- opMDRP00011 = 0xc3 // .
- opMDRP00100 = 0xc4 // .
- opMDRP00101 = 0xc5 // .
- opMDRP00110 = 0xc6 // .
- opMDRP00111 = 0xc7 // .
- opMDRP01000 = 0xc8 // .
- opMDRP01001 = 0xc9 // .
- opMDRP01010 = 0xca // .
- opMDRP01011 = 0xcb // .
- opMDRP01100 = 0xcc // .
- opMDRP01101 = 0xcd // .
- opMDRP01110 = 0xce // .
- opMDRP01111 = 0xcf // .
- opMDRP10000 = 0xd0 // .
- opMDRP10001 = 0xd1 // .
- opMDRP10010 = 0xd2 // .
- opMDRP10011 = 0xd3 // .
- opMDRP10100 = 0xd4 // .
- opMDRP10101 = 0xd5 // .
- opMDRP10110 = 0xd6 // .
- opMDRP10111 = 0xd7 // .
- opMDRP11000 = 0xd8 // .
- opMDRP11001 = 0xd9 // .
- opMDRP11010 = 0xda // .
- opMDRP11011 = 0xdb // .
- opMDRP11100 = 0xdc // .
- opMDRP11101 = 0xdd // .
- opMDRP11110 = 0xde // .
- opMDRP11111 = 0xdf // .
- opMIRP00000 = 0xe0 // Move Indirect Relative Point
- opMIRP00001 = 0xe1 // .
- opMIRP00010 = 0xe2 // .
- opMIRP00011 = 0xe3 // .
- opMIRP00100 = 0xe4 // .
- opMIRP00101 = 0xe5 // .
- opMIRP00110 = 0xe6 // .
- opMIRP00111 = 0xe7 // .
- opMIRP01000 = 0xe8 // .
- opMIRP01001 = 0xe9 // .
- opMIRP01010 = 0xea // .
- opMIRP01011 = 0xeb // .
- opMIRP01100 = 0xec // .
- opMIRP01101 = 0xed // .
- opMIRP01110 = 0xee // .
- opMIRP01111 = 0xef // .
- opMIRP10000 = 0xf0 // .
- opMIRP10001 = 0xf1 // .
- opMIRP10010 = 0xf2 // .
- opMIRP10011 = 0xf3 // .
- opMIRP10100 = 0xf4 // .
- opMIRP10101 = 0xf5 // .
- opMIRP10110 = 0xf6 // .
- opMIRP10111 = 0xf7 // .
- opMIRP11000 = 0xf8 // .
- opMIRP11001 = 0xf9 // .
- opMIRP11010 = 0xfa // .
- opMIRP11011 = 0xfb // .
- opMIRP11100 = 0xfc // .
- opMIRP11101 = 0xfd // .
- opMIRP11110 = 0xfe // .
- opMIRP11111 = 0xff // .
-)
-
-// popCount is the number of stack elements that each opcode pops.
-var popCount = [256]uint8{
- // 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
- 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 5, // 0x00 - 0x0f
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, // 0x10 - 0x1f
- 1, 1, 0, 2, 0, 1, 1, 2, 0, 1, 2, 1, 1, 0, 1, 1, // 0x20 - 0x2f
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 2, 2, 0, 0, 2, 2, // 0x30 - 0x3f
- 0, 0, 2, 1, 2, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, // 0x40 - 0x4f
- 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 2, 2, 1, 1, 1, 1, // 0x50 - 0x5f
- 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6f
- 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 1, 1, // 0x70 - 0x7f
- 0, 2, 2, 0, 0, 1, 2, 2, 1, 1, 3, 2, 2, 1, 2, 0, // 0x80 - 0x8f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90 - 0x9f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0 - 0xaf
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0 - 0xbf
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 0xcf
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 0xdf
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 0xef
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xf0 - 0xff
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype.go
deleted file mode 100644
index 692e01526..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype.go
+++ /dev/null
@@ -1,639 +0,0 @@
-// Copyright 2010 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-// Package truetype provides a parser for the TTF and TTC file formats.
-// Those formats are documented at http://developer.apple.com/fonts/TTRefMan/
-// and http://www.microsoft.com/typography/otspec/
-//
-// Some of a font's methods provide lengths or co-ordinates, e.g. bounds, font
-// metrics and control points. All these methods take a scale parameter, which
-// is the number of pixels in 1 em, expressed as a 26.6 fixed point value. For
-// example, if 1 em is 10 pixels then scale is fixed.I(10), which is equal to
-// fixed.Int26_6(10 << 6).
-//
-// To measure a TrueType font in ideal FUnit space, use scale equal to
-// font.FUnitsPerEm().
-package truetype
-
-import (
- "fmt"
-
- "golang.org/x/image/math/fixed"
-)
-
-// An Index is a Font's index of a rune.
-type Index uint16
-
-// A NameID identifies a name table entry.
-//
-// See https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
-type NameID uint16
-
-const (
- NameIDCopyright NameID = 0
- NameIDFontFamily = 1
- NameIDFontSubfamily = 2
- NameIDUniqueSubfamilyID = 3
- NameIDFontFullName = 4
- NameIDNameTableVersion = 5
- NameIDPostscriptName = 6
- NameIDTrademarkNotice = 7
- NameIDManufacturerName = 8
- NameIDDesignerName = 9
- NameIDFontDescription = 10
- NameIDFontVendorURL = 11
- NameIDFontDesignerURL = 12
- NameIDFontLicense = 13
- NameIDFontLicenseURL = 14
- NameIDPreferredFamily = 16
- NameIDPreferredSubfamily = 17
- NameIDCompatibleName = 18
- NameIDSampleText = 19
-)
-
-const (
- // A 32-bit encoding consists of a most-significant 16-bit Platform ID and a
- // least-significant 16-bit Platform Specific ID. The magic numbers are
- // specified at https://www.microsoft.com/typography/otspec/name.htm
- unicodeEncoding = 0x00000003 // PID = 0 (Unicode), PSID = 3 (Unicode 2.0)
- microsoftSymbolEncoding = 0x00030000 // PID = 3 (Microsoft), PSID = 0 (Symbol)
- microsoftUCS2Encoding = 0x00030001 // PID = 3 (Microsoft), PSID = 1 (UCS-2)
- microsoftUCS4Encoding = 0x0003000a // PID = 3 (Microsoft), PSID = 10 (UCS-4)
-)
-
-// An HMetric holds the horizontal metrics of a single glyph.
-type HMetric struct {
- AdvanceWidth, LeftSideBearing fixed.Int26_6
-}
-
-// A VMetric holds the vertical metrics of a single glyph.
-type VMetric struct {
- AdvanceHeight, TopSideBearing fixed.Int26_6
-}
-
-// A FormatError reports that the input is not a valid TrueType font.
-type FormatError string
-
-func (e FormatError) Error() string {
- return "freetype: invalid TrueType format: " + string(e)
-}
-
-// An UnsupportedError reports that the input uses a valid but unimplemented
-// TrueType feature.
-type UnsupportedError string
-
-func (e UnsupportedError) Error() string {
- return "freetype: unsupported TrueType feature: " + string(e)
-}
-
-// u32 returns the big-endian uint32 at b[i:].
-func u32(b []byte, i int) uint32 {
- return uint32(b[i])<<24 | uint32(b[i+1])<<16 | uint32(b[i+2])<<8 | uint32(b[i+3])
-}
-
-// u16 returns the big-endian uint16 at b[i:].
-func u16(b []byte, i int) uint16 {
- return uint16(b[i])<<8 | uint16(b[i+1])
-}
-
-// readTable returns a slice of the TTF data given by a table's directory entry.
-func readTable(ttf []byte, offsetLength []byte) ([]byte, error) {
- offset := int(u32(offsetLength, 0))
- if offset < 0 {
- return nil, FormatError(fmt.Sprintf("offset too large: %d", uint32(offset)))
- }
- length := int(u32(offsetLength, 4))
- if length < 0 {
- return nil, FormatError(fmt.Sprintf("length too large: %d", uint32(length)))
- }
- end := offset + length
- if end < 0 || end > len(ttf) {
- return nil, FormatError(fmt.Sprintf("offset + length too large: %d", uint32(offset)+uint32(length)))
- }
- return ttf[offset:end], nil
-}
-
-// parseSubtables returns the offset and platformID of the best subtable in
-// table, where best favors a Unicode cmap encoding, and failing that, a
-// Microsoft cmap encoding. offset is the offset of the first subtable in
-// table, and size is the size of each subtable.
-//
-// If pred is non-nil, then only subtables that satisfy that predicate will be
-// considered.
-func parseSubtables(table []byte, name string, offset, size int, pred func([]byte) bool) (
- bestOffset int, bestPID uint32, retErr error) {
-
- if len(table) < 4 {
- return 0, 0, FormatError(name + " too short")
- }
- nSubtables := int(u16(table, 2))
- if len(table) < size*nSubtables+offset {
- return 0, 0, FormatError(name + " too short")
- }
- ok := false
- for i := 0; i < nSubtables; i, offset = i+1, offset+size {
- if pred != nil && !pred(table[offset:]) {
- continue
- }
- // We read the 16-bit Platform ID and 16-bit Platform Specific ID as a single uint32.
- // All values are big-endian.
- pidPsid := u32(table, offset)
- // We prefer the Unicode cmap encoding. Failing to find that, we fall
- // back onto the Microsoft cmap encoding.
- if pidPsid == unicodeEncoding {
- bestOffset, bestPID, ok = offset, pidPsid>>16, true
- break
-
- } else if pidPsid == microsoftSymbolEncoding ||
- pidPsid == microsoftUCS2Encoding ||
- pidPsid == microsoftUCS4Encoding {
-
- bestOffset, bestPID, ok = offset, pidPsid>>16, true
- // We don't break out of the for loop, so that Unicode can override Microsoft.
- }
- }
- if !ok {
- return 0, 0, UnsupportedError(name + " encoding")
- }
- return bestOffset, bestPID, nil
-}
-
-const (
- locaOffsetFormatUnknown int = iota
- locaOffsetFormatShort
- locaOffsetFormatLong
-)
-
-// A cm holds a parsed cmap entry.
-type cm struct {
- start, end, delta, offset uint32
-}
-
-// A Font represents a Truetype font.
-type Font struct {
- // Tables sliced from the TTF data. The different tables are documented
- // at http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html
- cmap, cvt, fpgm, glyf, hdmx, head, hhea, hmtx, kern, loca, maxp, name, os2, prep, vmtx []byte
-
- cmapIndexes []byte
-
- // Cached values derived from the raw ttf data.
- cm []cm
- locaOffsetFormat int
- nGlyph, nHMetric, nKern int
- fUnitsPerEm int32
- bounds fixed.Rectangle26_6
- // Values from the maxp section.
- maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16
-}
-
-func (f *Font) parseCmap() error {
- const (
- cmapFormat4 = 4
- cmapFormat12 = 12
- languageIndependent = 0
- )
-
- offset, _, err := parseSubtables(f.cmap, "cmap", 4, 8, nil)
- if err != nil {
- return err
- }
- offset = int(u32(f.cmap, offset+4))
- if offset <= 0 || offset > len(f.cmap) {
- return FormatError("bad cmap offset")
- }
-
- cmapFormat := u16(f.cmap, offset)
- switch cmapFormat {
- case cmapFormat4:
- language := u16(f.cmap, offset+4)
- if language != languageIndependent {
- return UnsupportedError(fmt.Sprintf("language: %d", language))
- }
- segCountX2 := int(u16(f.cmap, offset+6))
- if segCountX2%2 == 1 {
- return FormatError(fmt.Sprintf("bad segCountX2: %d", segCountX2))
- }
- segCount := segCountX2 / 2
- offset += 14
- f.cm = make([]cm, segCount)
- for i := 0; i < segCount; i++ {
- f.cm[i].end = uint32(u16(f.cmap, offset))
- offset += 2
- }
- offset += 2
- for i := 0; i < segCount; i++ {
- f.cm[i].start = uint32(u16(f.cmap, offset))
- offset += 2
- }
- for i := 0; i < segCount; i++ {
- f.cm[i].delta = uint32(u16(f.cmap, offset))
- offset += 2
- }
- for i := 0; i < segCount; i++ {
- f.cm[i].offset = uint32(u16(f.cmap, offset))
- offset += 2
- }
- f.cmapIndexes = f.cmap[offset:]
- return nil
-
- case cmapFormat12:
- if u16(f.cmap, offset+2) != 0 {
- return FormatError(fmt.Sprintf("cmap format: % x", f.cmap[offset:offset+4]))
- }
- length := u32(f.cmap, offset+4)
- language := u32(f.cmap, offset+8)
- if language != languageIndependent {
- return UnsupportedError(fmt.Sprintf("language: %d", language))
- }
- nGroups := u32(f.cmap, offset+12)
- if length != 12*nGroups+16 {
- return FormatError("inconsistent cmap length")
- }
- offset += 16
- f.cm = make([]cm, nGroups)
- for i := uint32(0); i < nGroups; i++ {
- f.cm[i].start = u32(f.cmap, offset+0)
- f.cm[i].end = u32(f.cmap, offset+4)
- f.cm[i].delta = u32(f.cmap, offset+8) - f.cm[i].start
- offset += 12
- }
- return nil
- }
- return UnsupportedError(fmt.Sprintf("cmap format: %d", cmapFormat))
-}
-
-func (f *Font) parseHead() error {
- if len(f.head) != 54 {
- return FormatError(fmt.Sprintf("bad head length: %d", len(f.head)))
- }
- f.fUnitsPerEm = int32(u16(f.head, 18))
- f.bounds.Min.X = fixed.Int26_6(int16(u16(f.head, 36)))
- f.bounds.Min.Y = fixed.Int26_6(int16(u16(f.head, 38)))
- f.bounds.Max.X = fixed.Int26_6(int16(u16(f.head, 40)))
- f.bounds.Max.Y = fixed.Int26_6(int16(u16(f.head, 42)))
- switch i := u16(f.head, 50); i {
- case 0:
- f.locaOffsetFormat = locaOffsetFormatShort
- case 1:
- f.locaOffsetFormat = locaOffsetFormatLong
- default:
- return FormatError(fmt.Sprintf("bad indexToLocFormat: %d", i))
- }
- return nil
-}
-
-func (f *Font) parseHhea() error {
- if len(f.hhea) != 36 {
- return FormatError(fmt.Sprintf("bad hhea length: %d", len(f.hhea)))
- }
- f.nHMetric = int(u16(f.hhea, 34))
- if 4*f.nHMetric+2*(f.nGlyph-f.nHMetric) != len(f.hmtx) {
- return FormatError(fmt.Sprintf("bad hmtx length: %d", len(f.hmtx)))
- }
- return nil
-}
-
-func (f *Font) parseKern() error {
- // Apple's TrueType documentation (http://developer.apple.com/fonts/TTRefMan/RM06/Chap6kern.html) says:
- // "Previous versions of the 'kern' table defined both the version and nTables fields in the header
- // as UInt16 values and not UInt32 values. Use of the older format on the Mac OS is discouraged
- // (although AAT can sense an old kerning table and still make correct use of it). Microsoft
- // Windows still uses the older format for the 'kern' table and will not recognize the newer one.
- // Fonts targeted for the Mac OS only should use the new format; fonts targeted for both the Mac OS
- // and Windows should use the old format."
- // Since we expect that almost all fonts aim to be Windows-compatible, we only parse the "older" format,
- // just like the C Freetype implementation.
- if len(f.kern) == 0 {
- if f.nKern != 0 {
- return FormatError("bad kern table length")
- }
- return nil
- }
- if len(f.kern) < 18 {
- return FormatError("kern data too short")
- }
- version, offset := u16(f.kern, 0), 2
- if version != 0 {
- return UnsupportedError(fmt.Sprintf("kern version: %d", version))
- }
- n, offset := u16(f.kern, offset), offset+2
- if n != 1 {
- return UnsupportedError(fmt.Sprintf("kern nTables: %d", n))
- }
- offset += 2
- length, offset := int(u16(f.kern, offset)), offset+2
- coverage, offset := u16(f.kern, offset), offset+2
- if coverage != 0x0001 {
- // We only support horizontal kerning.
- return UnsupportedError(fmt.Sprintf("kern coverage: 0x%04x", coverage))
- }
- f.nKern, offset = int(u16(f.kern, offset)), offset+2
- if 6*f.nKern != length-14 {
- return FormatError("bad kern table length")
- }
- return nil
-}
-
-func (f *Font) parseMaxp() error {
- if len(f.maxp) != 32 {
- return FormatError(fmt.Sprintf("bad maxp length: %d", len(f.maxp)))
- }
- f.nGlyph = int(u16(f.maxp, 4))
- f.maxTwilightPoints = u16(f.maxp, 16)
- f.maxStorage = u16(f.maxp, 18)
- f.maxFunctionDefs = u16(f.maxp, 20)
- f.maxStackElements = u16(f.maxp, 24)
- return nil
-}
-
-// scale returns x divided by f.fUnitsPerEm, rounded to the nearest integer.
-func (f *Font) scale(x fixed.Int26_6) fixed.Int26_6 {
- if x >= 0 {
- x += fixed.Int26_6(f.fUnitsPerEm) / 2
- } else {
- x -= fixed.Int26_6(f.fUnitsPerEm) / 2
- }
- return x / fixed.Int26_6(f.fUnitsPerEm)
-}
-
-// Bounds returns the union of a Font's glyphs' bounds.
-func (f *Font) Bounds(scale fixed.Int26_6) fixed.Rectangle26_6 {
- b := f.bounds
- b.Min.X = f.scale(scale * b.Min.X)
- b.Min.Y = f.scale(scale * b.Min.Y)
- b.Max.X = f.scale(scale * b.Max.X)
- b.Max.Y = f.scale(scale * b.Max.Y)
- return b
-}
-
-// FUnitsPerEm returns the number of FUnits in a Font's em-square's side.
-func (f *Font) FUnitsPerEm() int32 {
- return f.fUnitsPerEm
-}
-
-// Index returns a Font's index for the given rune.
-func (f *Font) Index(x rune) Index {
- c := uint32(x)
- for i, j := 0, len(f.cm); i < j; {
- h := i + (j-i)/2
- cm := &f.cm[h]
- if c < cm.start {
- j = h
- } else if cm.end < c {
- i = h + 1
- } else if cm.offset == 0 {
- return Index(c + cm.delta)
- } else {
- offset := int(cm.offset) + 2*(h-len(f.cm)+int(c-cm.start))
- return Index(u16(f.cmapIndexes, offset))
- }
- }
- return 0
-}
-
-// Name returns the Font's name value for the given NameID. It returns "" if
-// there was an error, or if that name was not found.
-func (f *Font) Name(id NameID) string {
- x, platformID, err := parseSubtables(f.name, "name", 6, 12, func(b []byte) bool {
- return NameID(u16(b, 6)) == id
- })
- if err != nil {
- return ""
- }
- offset, length := u16(f.name, 4)+u16(f.name, x+10), u16(f.name, x+8)
- // Return the ASCII value of the encoded string.
- // The string is encoded as UTF-16 on non-Apple platformIDs; Apple is platformID 1.
- src := f.name[offset : offset+length]
- var dst []byte
- if platformID != 1 { // UTF-16.
- if len(src)&1 != 0 {
- return ""
- }
- dst = make([]byte, len(src)/2)
- for i := range dst {
- dst[i] = printable(u16(src, 2*i))
- }
- } else { // ASCII.
- dst = make([]byte, len(src))
- for i, c := range src {
- dst[i] = printable(uint16(c))
- }
- }
- return string(dst)
-}
-
-func printable(r uint16) byte {
- if 0x20 <= r && r < 0x7f {
- return byte(r)
- }
- return '?'
-}
-
-// unscaledHMetric returns the unscaled horizontal metrics for the glyph with
-// the given index.
-func (f *Font) unscaledHMetric(i Index) (h HMetric) {
- j := int(i)
- if j < 0 || f.nGlyph <= j {
- return HMetric{}
- }
- if j >= f.nHMetric {
- p := 4 * (f.nHMetric - 1)
- return HMetric{
- AdvanceWidth: fixed.Int26_6(u16(f.hmtx, p)),
- LeftSideBearing: fixed.Int26_6(int16(u16(f.hmtx, p+2*(j-f.nHMetric)+4))),
- }
- }
- return HMetric{
- AdvanceWidth: fixed.Int26_6(u16(f.hmtx, 4*j)),
- LeftSideBearing: fixed.Int26_6(int16(u16(f.hmtx, 4*j+2))),
- }
-}
-
-// HMetric returns the horizontal metrics for the glyph with the given index.
-func (f *Font) HMetric(scale fixed.Int26_6, i Index) HMetric {
- h := f.unscaledHMetric(i)
- h.AdvanceWidth = f.scale(scale * h.AdvanceWidth)
- h.LeftSideBearing = f.scale(scale * h.LeftSideBearing)
- return h
-}
-
-// unscaledVMetric returns the unscaled vertical metrics for the glyph with
-// the given index. yMax is the top of the glyph's bounding box.
-func (f *Font) unscaledVMetric(i Index, yMax fixed.Int26_6) (v VMetric) {
- j := int(i)
- if j < 0 || f.nGlyph <= j {
- return VMetric{}
- }
- if 4*j+4 <= len(f.vmtx) {
- return VMetric{
- AdvanceHeight: fixed.Int26_6(u16(f.vmtx, 4*j)),
- TopSideBearing: fixed.Int26_6(int16(u16(f.vmtx, 4*j+2))),
- }
- }
- // The OS/2 table has grown over time.
- // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6OS2.html
- // says that it was originally 68 bytes. Optional fields, including
- // the ascender and descender, are described at
- // http://www.microsoft.com/typography/otspec/os2.htm
- if len(f.os2) >= 72 {
- sTypoAscender := fixed.Int26_6(int16(u16(f.os2, 68)))
- sTypoDescender := fixed.Int26_6(int16(u16(f.os2, 70)))
- return VMetric{
- AdvanceHeight: sTypoAscender - sTypoDescender,
- TopSideBearing: sTypoAscender - yMax,
- }
- }
- return VMetric{
- AdvanceHeight: fixed.Int26_6(f.fUnitsPerEm),
- TopSideBearing: 0,
- }
-}
-
-// VMetric returns the vertical metrics for the glyph with the given index.
-func (f *Font) VMetric(scale fixed.Int26_6, i Index) VMetric {
- // TODO: should 0 be bounds.YMax?
- v := f.unscaledVMetric(i, 0)
- v.AdvanceHeight = f.scale(scale * v.AdvanceHeight)
- v.TopSideBearing = f.scale(scale * v.TopSideBearing)
- return v
-}
-
-// Kern returns the horizontal adjustment for the given glyph pair. A positive
-// kern means to move the glyphs further apart.
-func (f *Font) Kern(scale fixed.Int26_6, i0, i1 Index) fixed.Int26_6 {
- if f.nKern == 0 {
- return 0
- }
- g := uint32(i0)<<16 | uint32(i1)
- lo, hi := 0, f.nKern
- for lo < hi {
- i := (lo + hi) / 2
- ig := u32(f.kern, 18+6*i)
- if ig < g {
- lo = i + 1
- } else if ig > g {
- hi = i
- } else {
- return f.scale(scale * fixed.Int26_6(int16(u16(f.kern, 22+6*i))))
- }
- }
- return 0
-}
-
-// Parse returns a new Font for the given TTF or TTC data.
-//
-// For TrueType Collections, the first font in the collection is parsed.
-func Parse(ttf []byte) (font *Font, err error) {
- return parse(ttf, 0)
-}
-
-func parse(ttf []byte, offset int) (font *Font, err error) {
- if len(ttf)-offset < 12 {
- err = FormatError("TTF data is too short")
- return
- }
- originalOffset := offset
- magic, offset := u32(ttf, offset), offset+4
- switch magic {
- case 0x00010000:
- // No-op.
- case 0x74746366: // "ttcf" as a big-endian uint32.
- if originalOffset != 0 {
- err = FormatError("recursive TTC")
- return
- }
- ttcVersion, offset := u32(ttf, offset), offset+4
- if ttcVersion != 0x00010000 {
- // TODO: support TTC version 2.0, once I have such a .ttc file to test with.
- err = FormatError("bad TTC version")
- return
- }
- numFonts, offset := int(u32(ttf, offset)), offset+4
- if numFonts <= 0 {
- err = FormatError("bad number of TTC fonts")
- return
- }
- if len(ttf[offset:])/4 < numFonts {
- err = FormatError("TTC offset table is too short")
- return
- }
- // TODO: provide an API to select which font in a TrueType collection to return,
- // not just the first one. This may require an API to parse a TTC's name tables,
- // so users of this package can select the font in a TTC by name.
- offset = int(u32(ttf, offset))
- if offset <= 0 || offset > len(ttf) {
- err = FormatError("bad TTC offset")
- return
- }
- return parse(ttf, offset)
- default:
- err = FormatError("bad TTF version")
- return
- }
- n, offset := int(u16(ttf, offset)), offset+2
- if len(ttf) < 16*n+12 {
- err = FormatError("TTF data is too short")
- return
- }
- f := new(Font)
- // Assign the table slices.
- for i := 0; i < n; i++ {
- x := 16*i + 12
- switch string(ttf[x : x+4]) {
- case "cmap":
- f.cmap, err = readTable(ttf, ttf[x+8:x+16])
- case "cvt ":
- f.cvt, err = readTable(ttf, ttf[x+8:x+16])
- case "fpgm":
- f.fpgm, err = readTable(ttf, ttf[x+8:x+16])
- case "glyf":
- f.glyf, err = readTable(ttf, ttf[x+8:x+16])
- case "hdmx":
- f.hdmx, err = readTable(ttf, ttf[x+8:x+16])
- case "head":
- f.head, err = readTable(ttf, ttf[x+8:x+16])
- case "hhea":
- f.hhea, err = readTable(ttf, ttf[x+8:x+16])
- case "hmtx":
- f.hmtx, err = readTable(ttf, ttf[x+8:x+16])
- case "kern":
- f.kern, err = readTable(ttf, ttf[x+8:x+16])
- case "loca":
- f.loca, err = readTable(ttf, ttf[x+8:x+16])
- case "maxp":
- f.maxp, err = readTable(ttf, ttf[x+8:x+16])
- case "name":
- f.name, err = readTable(ttf, ttf[x+8:x+16])
- case "OS/2":
- f.os2, err = readTable(ttf, ttf[x+8:x+16])
- case "prep":
- f.prep, err = readTable(ttf, ttf[x+8:x+16])
- case "vmtx":
- f.vmtx, err = readTable(ttf, ttf[x+8:x+16])
- }
- if err != nil {
- return
- }
- }
- // Parse and sanity-check the TTF data.
- if err = f.parseHead(); err != nil {
- return
- }
- if err = f.parseMaxp(); err != nil {
- return
- }
- if err = f.parseCmap(); err != nil {
- return
- }
- if err = f.parseKern(); err != nil {
- return
- }
- if err = f.parseHhea(); err != nil {
- return
- }
- font = f
- return
-}
diff --git a/Godeps/_workspace/src/github.com/golang/groupcache/LICENSE b/Godeps/_workspace/src/github.com/golang/groupcache/LICENSE
deleted file mode 100644
index 37ec93a14..000000000
--- a/Godeps/_workspace/src/github.com/golang/groupcache/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that entity.
-For the purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable copyright license to reproduce, prepare Derivative Works of,
-publicly display, publicly perform, sublicense, and distribute the Work and such
-Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable (except as stated in this section) patent license to make, have
-made, use, offer to sell, sell, import, and otherwise transfer the Work, where
-such license applies only to those patent claims licensable by such Contributor
-that are necessarily infringed by their Contribution(s) alone or by combination
-of their Contribution(s) with the Work to which such Contribution(s) was
-submitted. If You institute patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Work or a
-Contribution incorporated within the Work constitutes direct or contributory
-patent infringement, then any patent licenses granted to You under this License
-for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof
-in any medium, with or without modifications, and in Source or Object form,
-provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute,
-all copyright, patent, trademark, and attribution notices from the Source form
-of the Work, excluding those notices that do not pertain to any part of the
-Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any
-Derivative Works that You distribute must include a readable copy of the
-attribution notices contained within such NOTICE file, excluding those notices
-that do not pertain to any part of the Derivative Works, in at least one of the
-following places: within a NOTICE text file distributed as part of the
-Derivative Works; within the Source form or documentation, if provided along
-with the Derivative Works; or, within a display generated by the Derivative
-Works, if and wherever such third-party notices normally appear. The contents of
-the NOTICE file are for informational purposes only and do not modify the
-License. You may add Your own attribution notices within Derivative Works that
-You distribute, alongside or as an addendum to the NOTICE text from the Work,
-provided that such additional attribution notices cannot be construed as
-modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted
-for inclusion in the Work by You to the Licensor shall be under the terms and
-conditions of this License, without any additional terms or conditions.
-Notwithstanding the above, nothing herein shall supersede or modify the terms of
-any separate license agreement you may have executed with Licensor regarding
-such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks,
-service marks, or product names of the Licensor, except as required for
-reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the
-Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
-including, without limitation, any warranties or conditions of TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
-solely responsible for determining the appropriateness of using or
-redistributing the Work and assume any risks associated with Your exercise of
-permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence),
-contract, or otherwise, unless required by applicable law (such as deliberate
-and grossly negligent acts) or agreed to in writing, shall any Contributor be
-liable to You for damages, including any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License or
-out of the use or inability to use the Work (including but not limited to
-damages for loss of goodwill, work stoppage, computer failure or malfunction, or
-any and all other commercial damages or losses), even if such Contributor has
-been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to
-offer, and charge a fee for, acceptance of support, warranty, indemnity, or
-other liability obligations and/or rights consistent with this License. However,
-in accepting such obligations, You may act only on Your own behalf and on Your
-sole responsibility, not on behalf of any other Contributor, and only if You
-agree to indemnify, defend, and hold each Contributor harmless for any liability
-incurred by, or claims asserted against, such Contributor by reason of your
-accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work
-
-To apply the Apache License to your work, attach the following boilerplate
-notice, with the fields enclosed by brackets "[]" replaced with your own
-identifying information. (Don't include the brackets!) The text should be
-enclosed in the appropriate comment syntax for the file format. We also
-recommend that a file or class name and description of purpose be included on
-the same "printed page" as the copyright notice for easier identification within
-third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/Godeps/_workspace/src/github.com/golang/groupcache/lru/lru.go b/Godeps/_workspace/src/github.com/golang/groupcache/lru/lru.go
deleted file mode 100644
index cdfe2991f..000000000
--- a/Godeps/_workspace/src/github.com/golang/groupcache/lru/lru.go
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-Copyright 2013 Google 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 lru implements an LRU cache.
-package lru
-
-import "container/list"
-
-// Cache is an LRU cache. It is not safe for concurrent access.
-type Cache struct {
- // MaxEntries is the maximum number of cache entries before
- // an item is evicted. Zero means no limit.
- MaxEntries int
-
- // OnEvicted optionally specificies a callback function to be
- // executed when an entry is purged from the cache.
- OnEvicted func(key Key, value interface{})
-
- ll *list.List
- cache map[interface{}]*list.Element
-}
-
-// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
-type Key interface{}
-
-type entry struct {
- key Key
- value interface{}
-}
-
-// New creates a new Cache.
-// If maxEntries is zero, the cache has no limit and it's assumed
-// that eviction is done by the caller.
-func New(maxEntries int) *Cache {
- return &Cache{
- MaxEntries: maxEntries,
- ll: list.New(),
- cache: make(map[interface{}]*list.Element),
- }
-}
-
-// Add adds a value to the cache.
-func (c *Cache) Add(key Key, value interface{}) {
- if c.cache == nil {
- c.cache = make(map[interface{}]*list.Element)
- c.ll = list.New()
- }
- if ee, ok := c.cache[key]; ok {
- c.ll.MoveToFront(ee)
- ee.Value.(*entry).value = value
- return
- }
- ele := c.ll.PushFront(&entry{key, value})
- c.cache[key] = ele
- if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
- c.RemoveOldest()
- }
-}
-
-// Get looks up a key's value from the cache.
-func (c *Cache) Get(key Key) (value interface{}, ok bool) {
- if c.cache == nil {
- return
- }
- if ele, hit := c.cache[key]; hit {
- c.ll.MoveToFront(ele)
- return ele.Value.(*entry).value, true
- }
- return
-}
-
-// Remove removes the provided key from the cache.
-func (c *Cache) Remove(key Key) {
- if c.cache == nil {
- return
- }
- if ele, hit := c.cache[key]; hit {
- c.removeElement(ele)
- }
-}
-
-// RemoveOldest removes the oldest item from the cache.
-func (c *Cache) RemoveOldest() {
- if c.cache == nil {
- return
- }
- ele := c.ll.Back()
- if ele != nil {
- c.removeElement(ele)
- }
-}
-
-func (c *Cache) removeElement(e *list.Element) {
- c.ll.Remove(e)
- kv := e.Value.(*entry)
- delete(c.cache, kv.key)
- if c.OnEvicted != nil {
- c.OnEvicted(kv.key, kv.value)
- }
-}
-
-// Len returns the number of items in the cache.
-func (c *Cache) Len() int {
- if c.cache == nil {
- return 0
- }
- return c.ll.Len()
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml b/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml
deleted file mode 100644
index f983b60c6..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: go
-sudo: false
-
-go:
- - 1.3
- - 1.4
- - 1.5
- - tip
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/LICENSE b/Godeps/_workspace/src/github.com/gorilla/context/LICENSE
deleted file mode 100644
index 0e5fb8728..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/context/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/README.md b/Godeps/_workspace/src/github.com/gorilla/context/README.md
deleted file mode 100644
index c60a31b05..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/context/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-context
-=======
-[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)
-
-gorilla/context is a general purpose registry for global request variables.
-
-Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/context.go b/Godeps/_workspace/src/github.com/gorilla/context/context.go
deleted file mode 100644
index 81cb128b1..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/context/context.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package context
-
-import (
- "net/http"
- "sync"
- "time"
-)
-
-var (
- mutex sync.RWMutex
- data = make(map[*http.Request]map[interface{}]interface{})
- datat = make(map[*http.Request]int64)
-)
-
-// Set stores a value for a given key in a given request.
-func Set(r *http.Request, key, val interface{}) {
- mutex.Lock()
- if data[r] == nil {
- data[r] = make(map[interface{}]interface{})
- datat[r] = time.Now().Unix()
- }
- data[r][key] = val
- mutex.Unlock()
-}
-
-// Get returns a value stored for a given key in a given request.
-func Get(r *http.Request, key interface{}) interface{} {
- mutex.RLock()
- if ctx := data[r]; ctx != nil {
- value := ctx[key]
- mutex.RUnlock()
- return value
- }
- mutex.RUnlock()
- return nil
-}
-
-// GetOk returns stored value and presence state like multi-value return of map access.
-func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
- mutex.RLock()
- if _, ok := data[r]; ok {
- value, ok := data[r][key]
- mutex.RUnlock()
- return value, ok
- }
- mutex.RUnlock()
- return nil, false
-}
-
-// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
-func GetAll(r *http.Request) map[interface{}]interface{} {
- mutex.RLock()
- if context, ok := data[r]; ok {
- result := make(map[interface{}]interface{}, len(context))
- for k, v := range context {
- result[k] = v
- }
- mutex.RUnlock()
- return result
- }
- mutex.RUnlock()
- return nil
-}
-
-// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
-// the request was registered.
-func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
- mutex.RLock()
- context, ok := data[r]
- result := make(map[interface{}]interface{}, len(context))
- for k, v := range context {
- result[k] = v
- }
- mutex.RUnlock()
- return result, ok
-}
-
-// Delete removes a value stored for a given key in a given request.
-func Delete(r *http.Request, key interface{}) {
- mutex.Lock()
- if data[r] != nil {
- delete(data[r], key)
- }
- mutex.Unlock()
-}
-
-// Clear removes all values stored for a given request.
-//
-// This is usually called by a handler wrapper to clean up request
-// variables at the end of a request lifetime. See ClearHandler().
-func Clear(r *http.Request) {
- mutex.Lock()
- clear(r)
- mutex.Unlock()
-}
-
-// clear is Clear without the lock.
-func clear(r *http.Request) {
- delete(data, r)
- delete(datat, r)
-}
-
-// Purge removes request data stored for longer than maxAge, in seconds.
-// It returns the amount of requests removed.
-//
-// If maxAge <= 0, all request data is removed.
-//
-// This is only used for sanity check: in case context cleaning was not
-// properly set some request data can be kept forever, consuming an increasing
-// amount of memory. In case this is detected, Purge() must be called
-// periodically until the problem is fixed.
-func Purge(maxAge int) int {
- mutex.Lock()
- count := 0
- if maxAge <= 0 {
- count = len(data)
- data = make(map[*http.Request]map[interface{}]interface{})
- datat = make(map[*http.Request]int64)
- } else {
- min := time.Now().Unix() - int64(maxAge)
- for r := range data {
- if datat[r] < min {
- clear(r)
- count++
- }
- }
- }
- mutex.Unlock()
- return count
-}
-
-// ClearHandler wraps an http.Handler and clears request values at the end
-// of a request lifetime.
-func ClearHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- defer Clear(r)
- h.ServeHTTP(w, r)
- })
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/doc.go b/Godeps/_workspace/src/github.com/gorilla/context/doc.go
deleted file mode 100644
index 73c740031..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/context/doc.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package context stores values shared during a request lifetime.
-
-For example, a router can set variables extracted from the URL and later
-application handlers can access those values, or it can be used to store
-sessions values to be saved at the end of a request. There are several
-others common uses.
-
-The idea was posted by Brad Fitzpatrick to the go-nuts mailing list:
-
- http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53
-
-Here's the basic usage: first define the keys that you will need. The key
-type is interface{} so a key can be of any type that supports equality.
-Here we define a key using a custom int type to avoid name collisions:
-
- package foo
-
- import (
- "github.com/gorilla/context"
- )
-
- type key int
-
- const MyKey key = 0
-
-Then set a variable. Variables are bound to an http.Request object, so you
-need a request instance to set a value:
-
- context.Set(r, MyKey, "bar")
-
-The application can later access the variable using the same key you provided:
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // val is "bar".
- val := context.Get(r, foo.MyKey)
-
- // returns ("bar", true)
- val, ok := context.GetOk(r, foo.MyKey)
- // ...
- }
-
-And that's all about the basic usage. We discuss some other ideas below.
-
-Any type can be stored in the context. To enforce a given type, make the key
-private and wrap Get() and Set() to accept and return values of a specific
-type:
-
- type key int
-
- const mykey key = 0
-
- // GetMyKey returns a value for this package from the request values.
- func GetMyKey(r *http.Request) SomeType {
- if rv := context.Get(r, mykey); rv != nil {
- return rv.(SomeType)
- }
- return nil
- }
-
- // SetMyKey sets a value for this package in the request values.
- func SetMyKey(r *http.Request, val SomeType) {
- context.Set(r, mykey, val)
- }
-
-Variables must be cleared at the end of a request, to remove all values
-that were stored. This can be done in an http.Handler, after a request was
-served. Just call Clear() passing the request:
-
- context.Clear(r)
-
-...or use ClearHandler(), which conveniently wraps an http.Handler to clear
-variables at the end of a request lifetime.
-
-The Routers from the packages gorilla/mux and gorilla/pat call Clear()
-so if you are using either of them you don't need to clear the context manually.
-*/
-package context
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml b/Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
deleted file mode 100644
index ad1d76acc..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-language: go
-sudo: false
-
-matrix:
- include:
- - go: 1.4
- - go: 1.5
- - go: 1.6
-
-install:
- - go get golang.org/x/tools/cmd/vet
-
-script:
- - go get -t -v ./...
- - diff -u <(echo -n) <(gofmt -d .)
- - go tool vet .
- - go test -v -race ./...
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE b/Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE
deleted file mode 100644
index 66ea3c8ae..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 The Gorilla Handlers Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/README.md b/Godeps/_workspace/src/github.com/gorilla/handlers/README.md
deleted file mode 100644
index a782c4152..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-gorilla/handlers
-================
-[![GoDoc](https://godoc.org/github.com/gorilla/handlers?status.svg)](https://godoc.org/github.com/gorilla/handlers) [![Build Status](https://travis-ci.org/gorilla/handlers.svg?branch=master)](https://travis-ci.org/gorilla/handlers)
-
-Package handlers is a collection of handlers (aka "HTTP middleware") for use
-with Go's `net/http` package (or any framework supporting `http.Handler`), including:
-
-* [**LoggingHandler**](https://godoc.org/github.com/gorilla/handlers#LoggingHandler) for logging HTTP requests in the Apache [Common Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#common).
-* [**CombinedLoggingHandler**](https://godoc.org/github.com/gorilla/handlers#CombinedLoggingHandler) for logging HTTP requests in the Apache [Combined Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#combined) commonly used by
- both Apache and nginx.
-* [**CompressHandler**](https://godoc.org/github.com/gorilla/handlers#CompressHandler) for gzipping responses.
-* [**ContentTypeHandler**](https://godoc.org/github.com/gorilla/handlers#ContentTypeHandler) for validating requests against a list of accepted
- content types.
-* [**MethodHandler**](https://godoc.org/github.com/gorilla/handlers#MethodHandler) for matching HTTP methods against handlers in a
- `map[string]http.Handler`
-* [**ProxyHeaders**](https://godoc.org/github.com/gorilla/handlers#ProxyHeaders) for populating `r.RemoteAddr` and `r.URL.Scheme` based on the
- `X-Forwarded-For`, `X-Real-IP`, `X-Forwarded-Proto` and RFC7239 `Forwarded`
- headers when running a Go server behind a HTTP reverse proxy.
-* [**CanonicalHost**](https://godoc.org/github.com/gorilla/handlers#CanonicalHost) for re-directing to the preferred host when handling multiple
- domains (i.e. multiple CNAME aliases).
-* [**RecoveryHandler**](https://godoc.org/github.com/gorilla/handlers#RecoveryHandler) for recovering from unexpected panics.
-
-Other handlers are documented [on the Gorilla
-website](http://www.gorillatoolkit.org/pkg/handlers).
-
-## Example
-
-A simple example using `handlers.LoggingHandler` and `handlers.CompressHandler`:
-
-```go
-import (
- "net/http"
- "github.com/gorilla/handlers"
-)
-
-func main() {
- r := http.NewServeMux()
-
- // Only log requests to our admin dashboard to stdout
- r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
- r.HandleFunc("/", ShowIndex)
-
- // Wrap our server with our gzip handler to gzip compress all responses.
- http.ListenAndServe(":8000", handlers.CompressHandler(r))
-}
-```
-
-## License
-
-BSD licensed. See the included LICENSE file for details.
-
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go b/Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go
deleted file mode 100644
index 8437fefc1..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "net/url"
- "strings"
-)
-
-type canonical struct {
- h http.Handler
- domain string
- code int
-}
-
-// CanonicalHost is HTTP middleware that re-directs requests to the canonical
-// domain. It accepts a domain and a status code (e.g. 301 or 302) and
-// re-directs clients to this domain. The existing request path is maintained.
-//
-// Note: If the provided domain is considered invalid by url.Parse or otherwise
-// returns an empty scheme or host, clients are not re-directed.
-//
-// Example:
-//
-// r := mux.NewRouter()
-// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
-// r.HandleFunc("/route", YourHandler)
-//
-// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
-//
-func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
- fn := func(h http.Handler) http.Handler {
- return canonical{h, domain, code}
- }
-
- return fn
-}
-
-func (c canonical) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- dest, err := url.Parse(c.domain)
- if err != nil {
- // Call the next handler if the provided domain fails to parse.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if dest.Scheme == "" || dest.Host == "" {
- // Call the next handler if the scheme or host are empty.
- // Note that url.Parse won't fail on in this case.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if !strings.EqualFold(cleanHost(r.Host), dest.Host) {
- // Re-build the destination URL
- dest := dest.Scheme + "://" + dest.Host + r.URL.Path
- if r.URL.RawQuery != "" {
- dest += "?" + r.URL.RawQuery
- }
- http.Redirect(w, r, dest, c.code)
- return
- }
-
- c.h.ServeHTTP(w, r)
-}
-
-// cleanHost cleans invalid Host headers by stripping anything after '/' or ' '.
-// This is backported from Go 1.5 (in response to issue #11206) and attempts to
-// mitigate malformed Host headers that do not match the format in RFC7230.
-func cleanHost(in string) string {
- if i := strings.IndexAny(in, " /"); i != -1 {
- return in[:i]
- }
- return in
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/compress.go b/Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
deleted file mode 100644
index 5e140c503..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "compress/flate"
- "compress/gzip"
- "io"
- "net/http"
- "strings"
-)
-
-type compressResponseWriter struct {
- io.Writer
- http.ResponseWriter
- http.Hijacker
- http.Flusher
- http.CloseNotifier
-}
-
-func (w *compressResponseWriter) WriteHeader(c int) {
- w.ResponseWriter.Header().Del("Content-Length")
- w.ResponseWriter.WriteHeader(c)
-}
-
-func (w *compressResponseWriter) Header() http.Header {
- return w.ResponseWriter.Header()
-}
-
-func (w *compressResponseWriter) Write(b []byte) (int, error) {
- h := w.ResponseWriter.Header()
- if h.Get("Content-Type") == "" {
- h.Set("Content-Type", http.DetectContentType(b))
- }
- h.Del("Content-Length")
-
- return w.Writer.Write(b)
-}
-
-type flusher interface {
- Flush() error
-}
-
-func (w *compressResponseWriter) Flush() {
- // Flush compressed data if compressor supports it.
- if f, ok := w.Writer.(flusher); ok {
- f.Flush()
- }
- // Flush HTTP response.
- if w.Flusher != nil {
- w.Flusher.Flush()
- }
-}
-
-// CompressHandler gzip compresses HTTP responses for clients that support it
-// via the 'Accept-Encoding' header.
-func CompressHandler(h http.Handler) http.Handler {
- return CompressHandlerLevel(h, gzip.DefaultCompression)
-}
-
-// CompressHandlerLevel gzip compresses HTTP responses with specified compression level
-// for clients that support it via the 'Accept-Encoding' header.
-//
-// The compression level should be gzip.DefaultCompression, gzip.NoCompression,
-// or any integer value between gzip.BestSpeed and gzip.BestCompression inclusive.
-// gzip.DefaultCompression is used in case of invalid compression level.
-func CompressHandlerLevel(h http.Handler, level int) http.Handler {
- if level < gzip.DefaultCompression || level > gzip.BestCompression {
- level = gzip.DefaultCompression
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- L:
- for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") {
- switch strings.TrimSpace(enc) {
- case "gzip":
- w.Header().Set("Content-Encoding", "gzip")
- w.Header().Add("Vary", "Accept-Encoding")
-
- gw, _ := gzip.NewWriterLevel(w, level)
- defer gw.Close()
-
- h, hok := w.(http.Hijacker)
- if !hok { /* w is not Hijacker... oh well... */
- h = nil
- }
-
- f, fok := w.(http.Flusher)
- if !fok {
- f = nil
- }
-
- cn, cnok := w.(http.CloseNotifier)
- if !cnok {
- cn = nil
- }
-
- w = &compressResponseWriter{
- Writer: gw,
- ResponseWriter: w,
- Hijacker: h,
- Flusher: f,
- CloseNotifier: cn,
- }
-
- break L
- case "deflate":
- w.Header().Set("Content-Encoding", "deflate")
- w.Header().Add("Vary", "Accept-Encoding")
-
- fw, _ := flate.NewWriter(w, level)
- defer fw.Close()
-
- h, hok := w.(http.Hijacker)
- if !hok { /* w is not Hijacker... oh well... */
- h = nil
- }
-
- f, fok := w.(http.Flusher)
- if !fok {
- f = nil
- }
-
- cn, cnok := w.(http.CloseNotifier)
- if !cnok {
- cn = nil
- }
-
- w = &compressResponseWriter{
- Writer: fw,
- ResponseWriter: w,
- Hijacker: h,
- Flusher: f,
- CloseNotifier: cn,
- }
-
- break L
- }
- }
-
- h.ServeHTTP(w, r)
- })
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/cors.go b/Godeps/_workspace/src/github.com/gorilla/handlers/cors.go
deleted file mode 100644
index 1f92d1ad4..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/cors.go
+++ /dev/null
@@ -1,317 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "strconv"
- "strings"
-)
-
-// CORSOption represents a functional option for configuring the CORS middleware.
-type CORSOption func(*cors) error
-
-type cors struct {
- h http.Handler
- allowedHeaders []string
- allowedMethods []string
- allowedOrigins []string
- allowedOriginValidator OriginValidator
- exposedHeaders []string
- maxAge int
- ignoreOptions bool
- allowCredentials bool
-}
-
-// OriginValidator takes an origin string and returns whether or not that origin is allowed.
-type OriginValidator func(string) bool
-
-var (
- defaultCorsMethods = []string{"GET", "HEAD", "POST"}
- defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
- // (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
-)
-
-const (
- corsOptionMethod string = "OPTIONS"
- corsAllowOriginHeader string = "Access-Control-Allow-Origin"
- corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
- corsMaxAgeHeader string = "Access-Control-Max-Age"
- corsAllowMethodsHeader string = "Access-Control-Allow-Methods"
- corsAllowHeadersHeader string = "Access-Control-Allow-Headers"
- corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
- corsRequestMethodHeader string = "Access-Control-Request-Method"
- corsRequestHeadersHeader string = "Access-Control-Request-Headers"
- corsOriginHeader string = "Origin"
- corsVaryHeader string = "Vary"
- corsOriginMatchAll string = "*"
-)
-
-func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- origin := r.Header.Get(corsOriginHeader)
- if !ch.isOriginAllowed(origin) {
- ch.h.ServeHTTP(w, r)
- return
- }
-
- if r.Method == corsOptionMethod {
- if ch.ignoreOptions {
- ch.h.ServeHTTP(w, r)
- return
- }
-
- if _, ok := r.Header[corsRequestMethodHeader]; !ok {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- method := r.Header.Get(corsRequestMethodHeader)
- if !ch.isMatch(method, ch.allowedMethods) {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
-
- requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
- allowedHeaders := []string{}
- for _, v := range requestHeaders {
- canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
- continue
- }
-
- if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
- w.WriteHeader(http.StatusForbidden)
- return
- }
-
- allowedHeaders = append(allowedHeaders, canonicalHeader)
- }
-
- if len(allowedHeaders) > 0 {
- w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
- }
-
- if ch.maxAge > 0 {
- w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
- }
-
- if !ch.isMatch(method, defaultCorsMethods) {
- w.Header().Set(corsAllowMethodsHeader, method)
- }
- } else {
- if len(ch.exposedHeaders) > 0 {
- w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
- }
- }
-
- if ch.allowCredentials {
- w.Header().Set(corsAllowCredentialsHeader, "true")
- }
-
- if len(ch.allowedOrigins) > 1 {
- w.Header().Set(corsVaryHeader, corsOriginHeader)
- }
-
- w.Header().Set(corsAllowOriginHeader, origin)
-
- if r.Method == corsOptionMethod {
- return
- }
- ch.h.ServeHTTP(w, r)
-}
-
-// CORS provides Cross-Origin Resource Sharing middleware.
-// Example:
-//
-// import (
-// "net/http"
-//
-// "github.com/gorilla/handlers"
-// "github.com/gorilla/mux"
-// )
-//
-// func main() {
-// r := mux.NewRouter()
-// r.HandleFunc("/users", UserEndpoint)
-// r.HandleFunc("/projects", ProjectEndpoint)
-//
-// // Apply the CORS middleware to our top-level router, with the defaults.
-// http.ListenAndServe(":8000", handlers.CORS()(r))
-// }
-//
-func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
- return func(h http.Handler) http.Handler {
- ch := parseCORSOptions(opts...)
- ch.h = h
- return ch
- }
-}
-
-func parseCORSOptions(opts ...CORSOption) *cors {
- ch := &cors{
- allowedMethods: defaultCorsMethods,
- allowedHeaders: defaultCorsHeaders,
- allowedOrigins: []string{corsOriginMatchAll},
- }
-
- for _, option := range opts {
- option(ch)
- }
-
- return ch
-}
-
-//
-// Functional options for configuring CORS.
-//
-
-// AllowedHeaders adds the provided headers to the list of allowed headers in a
-// CORS request.
-// This is an append operation so the headers Accept, Accept-Language,
-// and Content-Language are always allowed.
-// Content-Type must be explicitly declared if accepting Content-Types other than
-// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
-func AllowedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
- ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// AllowedMethods can be used to explicitly allow methods in the
-// Access-Control-Allow-Methods header.
-// This is a replacement operation so you must also
-// pass GET, HEAD, and POST if you wish to support those methods.
-func AllowedMethods(methods []string) CORSOption {
- return func(ch *cors) error {
- ch.allowedMethods = []string{}
- for _, v := range methods {
- normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
- if normalizedMethod == "" {
- continue
- }
-
- if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
- ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
- }
- }
-
- return nil
- }
-}
-
-// AllowedOrigins sets the allowed origins for CORS requests, as used in the
-// 'Allow-Access-Control-Origin' HTTP header.
-// Note: Passing in a []string{"*"} will allow any domain.
-func AllowedOrigins(origins []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range origins {
- if v == corsOriginMatchAll {
- ch.allowedOrigins = []string{corsOriginMatchAll}
- return nil
- }
- }
-
- ch.allowedOrigins = origins
- return nil
- }
-}
-
-// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
-// 'Allow-Access-Control-Origin' HTTP header.
-func AllowedOriginValidator(fn OriginValidator) CORSOption {
- return func(ch *cors) error {
- ch.allowedOriginValidator = fn
- return nil
- }
-}
-
-// ExposeHeaders can be used to specify headers that are available
-// and will not be stripped out by the user-agent.
-func ExposedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- ch.exposedHeaders = []string{}
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
- ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// MaxAge determines the maximum age (in seconds) between preflight requests. A
-// maximum of 10 minutes is allowed. An age above this value will default to 10
-// minutes.
-func MaxAge(age int) CORSOption {
- return func(ch *cors) error {
- // Maximum of 10 minutes.
- if age > 600 {
- age = 600
- }
-
- ch.maxAge = age
- return nil
- }
-}
-
-// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
-// passing them through to the next handler. This is useful when your application
-// or framework has a pre-existing mechanism for responding to OPTIONS requests.
-func IgnoreOptions() CORSOption {
- return func(ch *cors) error {
- ch.ignoreOptions = true
- return nil
- }
-}
-
-// AllowCredentials can be used to specify that the user agent may pass
-// authentication details along with the request.
-func AllowCredentials() CORSOption {
- return func(ch *cors) error {
- ch.allowCredentials = true
- return nil
- }
-}
-
-func (ch *cors) isOriginAllowed(origin string) bool {
- if origin == "" {
- return false
- }
-
- if ch.allowedOriginValidator != nil {
- return ch.allowedOriginValidator(origin)
- }
-
- for _, allowedOrigin := range ch.allowedOrigins {
- if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
- return true
- }
- }
-
- return false
-}
-
-func (ch *cors) isMatch(needle string, haystack []string) bool {
- for _, v := range haystack {
- if v == needle {
- return true
- }
- }
-
- return false
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/doc.go b/Godeps/_workspace/src/github.com/gorilla/handlers/doc.go
deleted file mode 100644
index 944e5a8ae..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/doc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-Package handlers is a collection of handlers (aka "HTTP middleware") for use
-with Go's net/http package (or any framework supporting http.Handler).
-
-The package includes handlers for logging in standardised formats, compressing
-HTTP responses, validating content types and other useful tools for manipulating
-requests and responses.
-*/
-package handlers
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go b/Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
deleted file mode 100644
index 9544d2f0a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "bufio"
- "fmt"
- "io"
- "net"
- "net/http"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-)
-
-// MethodHandler is an http.Handler that dispatches to a handler whose key in the
-// MethodHandler's map matches the name of the HTTP request's method, eg: GET
-//
-// If the request's method is OPTIONS and OPTIONS is not a key in the map then
-// the handler responds with a status of 200 and sets the Allow header to a
-// comma-separated list of available methods.
-//
-// If the request's method doesn't match any of its keys the handler responds
-// with a status of HTTP 405 "Method Not Allowed" and sets the Allow header to a
-// comma-separated list of available methods.
-type MethodHandler map[string]http.Handler
-
-func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- if handler, ok := h[req.Method]; ok {
- handler.ServeHTTP(w, req)
- } else {
- allow := []string{}
- for k := range h {
- allow = append(allow, k)
- }
- sort.Strings(allow)
- w.Header().Set("Allow", strings.Join(allow, ", "))
- if req.Method == "OPTIONS" {
- w.WriteHeader(http.StatusOK)
- } else {
- http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
- }
- }
-}
-
-// loggingHandler is the http.Handler implementation for LoggingHandlerTo and its
-// friends
-type loggingHandler struct {
- writer io.Writer
- handler http.Handler
-}
-
-// combinedLoggingHandler is the http.Handler implementation for LoggingHandlerTo
-// and its friends
-type combinedLoggingHandler struct {
- writer io.Writer
- handler http.Handler
-}
-
-func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- t := time.Now()
- logger := makeLogger(w)
- url := *req.URL
- h.handler.ServeHTTP(logger, req)
- writeLog(h.writer, req, url, t, logger.Status(), logger.Size())
-}
-
-func (h combinedLoggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- t := time.Now()
- logger := makeLogger(w)
- url := *req.URL
- h.handler.ServeHTTP(logger, req)
- writeCombinedLog(h.writer, req, url, t, logger.Status(), logger.Size())
-}
-
-func makeLogger(w http.ResponseWriter) loggingResponseWriter {
- var logger loggingResponseWriter = &responseLogger{w: w}
- if _, ok := w.(http.Hijacker); ok {
- logger = &hijackLogger{responseLogger{w: w}}
- }
- h, ok1 := logger.(http.Hijacker)
- c, ok2 := w.(http.CloseNotifier)
- if ok1 && ok2 {
- return hijackCloseNotifier{logger, h, c}
- }
- if ok2 {
- return &closeNotifyWriter{logger, c}
- }
- return logger
-}
-
-type loggingResponseWriter interface {
- http.ResponseWriter
- http.Flusher
- Status() int
- Size() int
-}
-
-// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
-// status code and body size
-type responseLogger struct {
- w http.ResponseWriter
- status int
- size int
-}
-
-func (l *responseLogger) Header() http.Header {
- return l.w.Header()
-}
-
-func (l *responseLogger) Write(b []byte) (int, error) {
- if l.status == 0 {
- // The status will be StatusOK if WriteHeader has not been called yet
- l.status = http.StatusOK
- }
- size, err := l.w.Write(b)
- l.size += size
- return size, err
-}
-
-func (l *responseLogger) WriteHeader(s int) {
- l.w.WriteHeader(s)
- l.status = s
-}
-
-func (l *responseLogger) Status() int {
- return l.status
-}
-
-func (l *responseLogger) Size() int {
- return l.size
-}
-
-func (l *responseLogger) Flush() {
- f, ok := l.w.(http.Flusher)
- if ok {
- f.Flush()
- }
-}
-
-type hijackLogger struct {
- responseLogger
-}
-
-func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- h := l.responseLogger.w.(http.Hijacker)
- conn, rw, err := h.Hijack()
- if err == nil && l.responseLogger.status == 0 {
- // The status will be StatusSwitchingProtocols if there was no error and
- // WriteHeader has not been called yet
- l.responseLogger.status = http.StatusSwitchingProtocols
- }
- return conn, rw, err
-}
-
-type closeNotifyWriter struct {
- loggingResponseWriter
- http.CloseNotifier
-}
-
-type hijackCloseNotifier struct {
- loggingResponseWriter
- http.Hijacker
- http.CloseNotifier
-}
-
-const lowerhex = "0123456789abcdef"
-
-func appendQuoted(buf []byte, s string) []byte {
- var runeTmp [utf8.UTFMax]byte
- for width := 0; len(s) > 0; s = s[width:] {
- r := rune(s[0])
- width = 1
- if r >= utf8.RuneSelf {
- r, width = utf8.DecodeRuneInString(s)
- }
- if width == 1 && r == utf8.RuneError {
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- continue
- }
- if r == rune('"') || r == '\\' { // always backslashed
- buf = append(buf, '\\')
- buf = append(buf, byte(r))
- continue
- }
- if strconv.IsPrint(r) {
- n := utf8.EncodeRune(runeTmp[:], r)
- buf = append(buf, runeTmp[:n]...)
- continue
- }
- switch r {
- case '\a':
- buf = append(buf, `\a`...)
- case '\b':
- buf = append(buf, `\b`...)
- case '\f':
- buf = append(buf, `\f`...)
- case '\n':
- buf = append(buf, `\n`...)
- case '\r':
- buf = append(buf, `\r`...)
- case '\t':
- buf = append(buf, `\t`...)
- case '\v':
- buf = append(buf, `\v`...)
- default:
- switch {
- case r < ' ':
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- case r > utf8.MaxRune:
- r = 0xFFFD
- fallthrough
- case r < 0x10000:
- buf = append(buf, `\u`...)
- for s := 12; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- default:
- buf = append(buf, `\U`...)
- for s := 28; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- }
- }
- }
- return buf
-
-}
-
-// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
- username := "-"
- if url.User != nil {
- if name := url.User.Username(); name != "" {
- username = name
- }
- }
-
- host, _, err := net.SplitHostPort(req.RemoteAddr)
-
- if err != nil {
- host = req.RemoteAddr
- }
-
- uri := req.RequestURI
-
- // Requests using the CONNECT method over HTTP/2.0 must use
- // the authority field (aka r.Host) to identify the target.
- // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
- if req.ProtoMajor == 2 && req.Method == "CONNECT" {
- uri = req.Host
- }
- if uri == "" {
- uri = url.RequestURI()
- }
-
- buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
- buf = append(buf, host...)
- buf = append(buf, " - "...)
- buf = append(buf, username...)
- buf = append(buf, " ["...)
- buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...)
- buf = append(buf, `] "`...)
- buf = append(buf, req.Method...)
- buf = append(buf, " "...)
- buf = appendQuoted(buf, uri)
- buf = append(buf, " "...)
- buf = append(buf, req.Proto...)
- buf = append(buf, `" `...)
- buf = append(buf, strconv.Itoa(status)...)
- buf = append(buf, " "...)
- buf = append(buf, strconv.Itoa(size)...)
- return buf
-}
-
-// writeLog writes a log entry for req to w in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func writeLog(w io.Writer, req *http.Request, url url.URL, ts time.Time, status, size int) {
- buf := buildCommonLogLine(req, url, ts, status, size)
- buf = append(buf, '\n')
- w.Write(buf)
-}
-
-// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func writeCombinedLog(w io.Writer, req *http.Request, url url.URL, ts time.Time, status, size int) {
- buf := buildCommonLogLine(req, url, ts, status, size)
- buf = append(buf, ` "`...)
- buf = appendQuoted(buf, req.Referer())
- buf = append(buf, `" "`...)
- buf = appendQuoted(buf, req.UserAgent())
- buf = append(buf, '"', '\n')
- w.Write(buf)
-}
-
-// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Combined Log Format.
-//
-// See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format.
-//
-// LoggingHandler always sets the ident field of the log to -
-func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
- return combinedLoggingHandler{out, h}
-}
-
-// LoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Common Log Format (CLF).
-//
-// See http://httpd.apache.org/docs/2.2/logs.html#common for a description of this format.
-//
-// LoggingHandler always sets the ident field of the log to -
-//
-// Example:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// w.Write([]byte("This is a catch-all route"))
-// })
-// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
-// http.ListenAndServe(":1123", loggedRouter)
-//
-func LoggingHandler(out io.Writer, h http.Handler) http.Handler {
- return loggingHandler{out, h}
-}
-
-// isContentType validates the Content-Type header matches the supplied
-// contentType. That is, its type and subtype match.
-func isContentType(h http.Header, contentType string) bool {
- ct := h.Get("Content-Type")
- if i := strings.IndexRune(ct, ';'); i != -1 {
- ct = ct[0:i]
- }
- return ct == contentType
-}
-
-// ContentTypeHandler wraps and returns a http.Handler, validating the request
-// content type is compatible with the contentTypes list. It writes a HTTP 415
-// error if that fails.
-//
-// Only PUT, POST, and PATCH requests are considered.
-func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if !(r.Method == "PUT" || r.Method == "POST" || r.Method == "PATCH") {
- h.ServeHTTP(w, r)
- return
- }
-
- for _, ct := range contentTypes {
- if isContentType(r.Header, ct) {
- h.ServeHTTP(w, r)
- return
- }
- }
- http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", r.Header.Get("Content-Type"), contentTypes), http.StatusUnsupportedMediaType)
- })
-}
-
-const (
- // HTTPMethodOverrideHeader is a commonly used
- // http header to override a request method.
- HTTPMethodOverrideHeader = "X-HTTP-Method-Override"
- // HTTPMethodOverrideFormKey is a commonly used
- // HTML form key to override a request method.
- HTTPMethodOverrideFormKey = "_method"
-)
-
-// HTTPMethodOverrideHandler wraps and returns a http.Handler which checks for
-// the X-HTTP-Method-Override header or the _method form key, and overrides (if
-// valid) request.Method with its value.
-//
-// This is especially useful for HTTP clients that don't support many http verbs.
-// It isn't secure to override e.g a GET to a POST, so only POST requests are
-// considered. Likewise, the override method can only be a "write" method: PUT,
-// PATCH or DELETE.
-//
-// Form method takes precedence over header method.
-func HTTPMethodOverrideHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "POST" {
- om := r.FormValue(HTTPMethodOverrideFormKey)
- if om == "" {
- om = r.Header.Get(HTTPMethodOverrideHeader)
- }
- if om == "PUT" || om == "PATCH" || om == "DELETE" {
- r.Method = om
- }
- }
- h.ServeHTTP(w, r)
- })
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go b/Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go
deleted file mode 100644
index 268de9c6a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "regexp"
- "strings"
-)
-
-var (
- // De-facto standard header keys.
- xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
- xRealIP = http.CanonicalHeaderKey("X-Real-IP")
- xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Scheme")
-)
-
-var (
- // RFC7239 defines a new "Forwarded: " header designed to replace the
- // existing use of X-Forwarded-* headers.
- // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43
- forwarded = http.CanonicalHeaderKey("Forwarded")
- // Allows for a sub-match of the first value after 'for=' to the next
- // comma, semi-colon or space. The match is case-insensitive.
- forRegex = regexp.MustCompile(`(?i)(?:for=)([^(;|,| )]+)`)
- // Allows for a sub-match for the first instance of scheme (http|https)
- // prefixed by 'proto='. The match is case-insensitive.
- protoRegex = regexp.MustCompile(`(?i)(?:proto=)(https|http)`)
-)
-
-// ProxyHeaders inspects common reverse proxy headers and sets the corresponding
-// fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP
-// for the remote (client) IP address, X-Forwarded-Proto for the scheme
-// (http|https) and the RFC7239 Forwarded header, which may include both client
-// IPs and schemes.
-//
-// NOTE: This middleware should only be used when behind a reverse
-// proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are
-// configured not to) strip these headers from client requests, or where these
-// headers are accepted "as is" from a remote client (e.g. when Go is not behind
-// a proxy), can manifest as a vulnerability if your application uses these
-// headers for validating the 'trustworthiness' of a request.
-func ProxyHeaders(h http.Handler) http.Handler {
- fn := func(w http.ResponseWriter, r *http.Request) {
- // Set the remote IP with the value passed from the proxy.
- if fwd := getIP(r); fwd != "" {
- r.RemoteAddr = fwd
- }
-
- // Set the scheme (proto) with the value passed from the proxy.
- if scheme := getScheme(r); scheme != "" {
- r.URL.Scheme = scheme
- }
-
- // Call the next handler in the chain.
- h.ServeHTTP(w, r)
- }
-
- return http.HandlerFunc(fn)
-}
-
-// getIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239
-// Forwarded headers (in that order).
-func getIP(r *http.Request) string {
- var addr string
-
- if fwd := r.Header.Get(xForwardedFor); fwd != "" {
- // Only grab the first (client) address. Note that '192.168.0.1,
- // 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
- // the first may represent forwarding proxies earlier in the chain.
- s := strings.Index(fwd, ", ")
- if s == -1 {
- s = len(fwd)
- }
- addr = fwd[:s]
- } else if fwd := r.Header.Get(xRealIP); fwd != "" {
- // X-Real-IP should only contain one IP address (the client making the
- // request).
- addr = fwd
- } else if fwd := r.Header.Get(forwarded); fwd != "" {
- // match should contain at least two elements if the protocol was
- // specified in the Forwarded header. The first element will always be
- // the 'for=' capture, which we ignore. In the case of multiple IP
- // addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only
- // extract the first, which should be the client IP.
- if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 {
- // IPv6 addresses in Forwarded headers are quoted-strings. We strip
- // these quotes.
- addr = strings.Trim(match[1], `"`)
- }
- }
-
- return addr
-}
-
-// getScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239
-// Forwarded headers (in that order).
-func getScheme(r *http.Request) string {
- var scheme string
-
- // Retrieve the scheme from X-Forwarded-Proto.
- if proto := r.Header.Get(xForwardedProto); proto != "" {
- scheme = strings.ToLower(proto)
- } else if proto := r.Header.Get(forwarded); proto != "" {
- // match should contain at least two elements if the protocol was
- // specified in the Forwarded header. The first element will always be
- // the 'proto=' capture, which we ignore. In the case of multiple proto
- // parameters (invalid) we only extract the first.
- if match := protoRegex.FindStringSubmatch(proto); len(match) > 1 {
- scheme = strings.ToLower(match[1])
- }
- }
-
- return scheme
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go b/Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go
deleted file mode 100644
index 65b7de58a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package handlers
-
-import (
- "log"
- "net/http"
- "runtime/debug"
-)
-
-type recoveryHandler struct {
- handler http.Handler
- logger *log.Logger
- printStack bool
-}
-
-// RecoveryOption provides a functional approach to define
-// configuration for a handler; such as setting the logging
-// whether or not to print strack traces on panic.
-type RecoveryOption func(http.Handler)
-
-func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
- for _, option := range opts {
- option(h)
- }
-
- return h
-}
-
-// RecoveryHandler is HTTP middleware that recovers from a panic,
-// logs the panic, writes http.StatusInternalServerError, and
-// continues to the next handler.
-//
-// Example:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// panic("Unexpected error!")
-// })
-//
-// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
-func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
- return func(h http.Handler) http.Handler {
- r := &recoveryHandler{handler: h}
- return parseRecoveryOptions(r, opts...)
- }
-}
-
-// RecoveryLogger is a functional option to override
-// the default logger
-func RecoveryLogger(logger *log.Logger) RecoveryOption {
- return func(h http.Handler) {
- r := h.(*recoveryHandler)
- r.logger = logger
- }
-}
-
-// PrintRecoveryStack is a functional option to enable
-// or disable printing stack traces on panic.
-func PrintRecoveryStack(print bool) RecoveryOption {
- return func(h http.Handler) {
- r := h.(*recoveryHandler)
- r.printStack = print
- }
-}
-
-func (h recoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- defer func() {
- if err := recover(); err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- h.log(err)
- }
- }()
-
- h.handler.ServeHTTP(w, req)
-}
-
-func (h recoveryHandler) log(message interface{}) {
- if h.logger != nil {
- h.logger.Println(message)
- } else {
- log.Println(message)
- }
-
- if h.printStack {
- debug.PrintStack()
- }
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml b/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml
deleted file mode 100644
index 83ab8f59d..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: go
-sudo: false
-go:
- - 1.3
- - 1.4
- - 1.5
- - tip
-install:
- - go get golang.org/x/tools/cmd/vet
-script:
- - go get -t -v ./...
- - diff -u <(echo -n) <(gofmt -d -s .)
- - go tool vet .
- - go test -v -race ./...
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE b/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE
deleted file mode 100644
index 0e5fb8728..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/README.md b/Godeps/_workspace/src/github.com/gorilla/mux/README.md
deleted file mode 100644
index 55dd4e59a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/README.md
+++ /dev/null
@@ -1,235 +0,0 @@
-mux
-===
-[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
-[![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux)
-
-Package gorilla/mux implements a request router and dispatcher.
-
-The name mux stands for "HTTP request multiplexer". Like the standard
-http.ServeMux, mux.Router matches incoming requests against a list of
-registered routes and calls a handler for the route that matches the URL
-or other conditions. The main features are:
-
- * Requests can be matched based on URL host, path, path prefix, schemes,
- header and query values, HTTP methods or using custom matchers.
- * URL hosts and paths can have variables with an optional regular
- expression.
- * Registered URLs can be built, or "reversed", which helps maintaining
- references to resources.
- * Routes can be used as subrouters: nested routes are only tested if the
- parent route matches. This is useful to define groups of routes that
- share common conditions like a host, a path prefix or other repeated
- attributes. As a bonus, this optimizes request matching.
- * It implements the http.Handler interface so it is compatible with the
- standard http.ServeMux.
-
-Let's start registering a couple of URL paths and handlers:
-
- func main() {
- r := mux.NewRouter()
- r.HandleFunc("/", HomeHandler)
- r.HandleFunc("/products", ProductsHandler)
- r.HandleFunc("/articles", ArticlesHandler)
- http.Handle("/", r)
- }
-
-Here we register three routes mapping URL paths to handlers. This is
-equivalent to how http.HandleFunc() works: if an incoming request URL matches
-one of the paths, the corresponding handler is called passing
-(http.ResponseWriter, *http.Request) as parameters.
-
-Paths can have variables. They are defined using the format {name} or
-{name:pattern}. If a regular expression pattern is not defined, the matched
-variable will be anything until the next slash. For example:
-
- r := mux.NewRouter()
- r.HandleFunc("/products/{key}", ProductHandler)
- r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
- r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
-
-The names are used to create a map of route variables which can be retrieved
-calling mux.Vars():
-
- vars := mux.Vars(request)
- category := vars["category"]
-
-And this is all you need to know about the basic usage. More advanced options
-are explained below.
-
-Routes can also be restricted to a domain or subdomain. Just define a host
-pattern to be matched. They can also have variables:
-
- r := mux.NewRouter()
- // Only matches if domain is "www.example.com".
- r.Host("www.example.com")
- // Matches a dynamic subdomain.
- r.Host("{subdomain:[a-z]+}.domain.com")
-
-There are several other matchers that can be added. To match path prefixes:
-
- r.PathPrefix("/products/")
-
-...or HTTP methods:
-
- r.Methods("GET", "POST")
-
-...or URL schemes:
-
- r.Schemes("https")
-
-...or header values:
-
- r.Headers("X-Requested-With", "XMLHttpRequest")
-
-...or query values:
-
- r.Queries("key", "value")
-
-...or to use a custom matcher function:
-
- r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
- return r.ProtoMajor == 0
- })
-
-...and finally, it is possible to combine several matchers in a single route:
-
- r.HandleFunc("/products", ProductsHandler).
- Host("www.example.com").
- Methods("GET").
- Schemes("http")
-
-Setting the same matching conditions again and again can be boring, so we have
-a way to group several routes that share the same requirements.
-We call it "subrouting".
-
-For example, let's say we have several URLs that should only match when the
-host is `www.example.com`. Create a route for that host and get a "subrouter"
-from it:
-
- r := mux.NewRouter()
- s := r.Host("www.example.com").Subrouter()
-
-Then register routes in the subrouter:
-
- s.HandleFunc("/products/", ProductsHandler)
- s.HandleFunc("/products/{key}", ProductHandler)
- s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
-
-The three URL paths we registered above will only be tested if the domain is
-`www.example.com`, because the subrouter is tested first. This is not
-only convenient, but also optimizes request matching. You can create
-subrouters combining any attribute matchers accepted by a route.
-
-Subrouters can be used to create domain or path "namespaces": you define
-subrouters in a central place and then parts of the app can register its
-paths relatively to a given subrouter.
-
-There's one more thing about subroutes. When a subrouter has a path prefix,
-the inner routes use it as base for their paths:
-
- r := mux.NewRouter()
- s := r.PathPrefix("/products").Subrouter()
- // "/products/"
- s.HandleFunc("/", ProductsHandler)
- // "/products/{key}/"
- s.HandleFunc("/{key}/", ProductHandler)
- // "/products/{key}/details"
- s.HandleFunc("/{key}/details", ProductDetailsHandler)
-
-Now let's see how to build registered URLs.
-
-Routes can be named. All routes that define a name can have their URLs built,
-or "reversed". We define a name calling Name() on a route. For example:
-
- r := mux.NewRouter()
- r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
- Name("article")
-
-To build a URL, get the route and call the URL() method, passing a sequence of
-key/value pairs for the route variables. For the previous route, we would do:
-
- url, err := r.Get("article").URL("category", "technology", "id", "42")
-
-...and the result will be a url.URL with the following path:
-
- "/articles/technology/42"
-
-This also works for host variables:
-
- r := mux.NewRouter()
- r.Host("{subdomain}.domain.com").
- Path("/articles/{category}/{id:[0-9]+}").
- HandlerFunc(ArticleHandler).
- Name("article")
-
- // url.String() will be "http://news.domain.com/articles/technology/42"
- url, err := r.Get("article").URL("subdomain", "news",
- "category", "technology",
- "id", "42")
-
-All variables defined in the route are required, and their values must
-conform to the corresponding patterns. These requirements guarantee that a
-generated URL will always match a registered route -- the only exception is
-for explicitly defined "build-only" routes which never match.
-
-Regex support also exists for matching Headers within a route. For example, we could do:
-
- r.HeadersRegexp("Content-Type", "application/(text|json)")
-
-...and the route will match both requests with a Content-Type of `application/json` as well as
-`application/text`
-
-There's also a way to build only the URL host or path for a route:
-use the methods URLHost() or URLPath() instead. For the previous route,
-we would do:
-
- // "http://news.domain.com/"
- host, err := r.Get("article").URLHost("subdomain", "news")
-
- // "/articles/technology/42"
- path, err := r.Get("article").URLPath("category", "technology", "id", "42")
-
-And if you use subrouters, host and path defined separately can be built
-as well:
-
- r := mux.NewRouter()
- s := r.Host("{subdomain}.domain.com").Subrouter()
- s.Path("/articles/{category}/{id:[0-9]+}").
- HandlerFunc(ArticleHandler).
- Name("article")
-
- // "http://news.domain.com/articles/technology/42"
- url, err := r.Get("article").URL("subdomain", "news",
- "category", "technology",
- "id", "42")
-
-## Full Example
-
-Here's a complete, runnable example of a small mux based server:
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gorilla/mux"
-)
-
-func YourHandler(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("Gorilla!\n"))
-}
-
-func main() {
- r := mux.NewRouter()
- // Routes consist of a path and a handler function.
- r.HandleFunc("/", YourHandler)
-
- // Bind to a port and pass our router in
- http.ListenAndServe(":8000", r)
-}
-```
-
-## License
-
-BSD licensed. See the LICENSE file for details.
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/doc.go b/Godeps/_workspace/src/github.com/gorilla/mux/doc.go
deleted file mode 100644
index 49798cb5c..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/doc.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package gorilla/mux implements a request router and dispatcher.
-
-The name mux stands for "HTTP request multiplexer". Like the standard
-http.ServeMux, mux.Router matches incoming requests against a list of
-registered routes and calls a handler for the route that matches the URL
-or other conditions. The main features are:
-
- * Requests can be matched based on URL host, path, path prefix, schemes,
- header and query values, HTTP methods or using custom matchers.
- * URL hosts and paths can have variables with an optional regular
- expression.
- * Registered URLs can be built, or "reversed", which helps maintaining
- references to resources.
- * Routes can be used as subrouters: nested routes are only tested if the
- parent route matches. This is useful to define groups of routes that
- share common conditions like a host, a path prefix or other repeated
- attributes. As a bonus, this optimizes request matching.
- * It implements the http.Handler interface so it is compatible with the
- standard http.ServeMux.
-
-Let's start registering a couple of URL paths and handlers:
-
- func main() {
- r := mux.NewRouter()
- r.HandleFunc("/", HomeHandler)
- r.HandleFunc("/products", ProductsHandler)
- r.HandleFunc("/articles", ArticlesHandler)
- http.Handle("/", r)
- }
-
-Here we register three routes mapping URL paths to handlers. This is
-equivalent to how http.HandleFunc() works: if an incoming request URL matches
-one of the paths, the corresponding handler is called passing
-(http.ResponseWriter, *http.Request) as parameters.
-
-Paths can have variables. They are defined using the format {name} or
-{name:pattern}. If a regular expression pattern is not defined, the matched
-variable will be anything until the next slash. For example:
-
- r := mux.NewRouter()
- r.HandleFunc("/products/{key}", ProductHandler)
- r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
- r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
-
-The names are used to create a map of route variables which can be retrieved
-calling mux.Vars():
-
- vars := mux.Vars(request)
- category := vars["category"]
-
-And this is all you need to know about the basic usage. More advanced options
-are explained below.
-
-Routes can also be restricted to a domain or subdomain. Just define a host
-pattern to be matched. They can also have variables:
-
- r := mux.NewRouter()
- // Only matches if domain is "www.example.com".
- r.Host("www.example.com")
- // Matches a dynamic subdomain.
- r.Host("{subdomain:[a-z]+}.domain.com")
-
-There are several other matchers that can be added. To match path prefixes:
-
- r.PathPrefix("/products/")
-
-...or HTTP methods:
-
- r.Methods("GET", "POST")
-
-...or URL schemes:
-
- r.Schemes("https")
-
-...or header values:
-
- r.Headers("X-Requested-With", "XMLHttpRequest")
-
-...or query values:
-
- r.Queries("key", "value")
-
-...or to use a custom matcher function:
-
- r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
- return r.ProtoMajor == 0
- })
-
-...and finally, it is possible to combine several matchers in a single route:
-
- r.HandleFunc("/products", ProductsHandler).
- Host("www.example.com").
- Methods("GET").
- Schemes("http")
-
-Setting the same matching conditions again and again can be boring, so we have
-a way to group several routes that share the same requirements.
-We call it "subrouting".
-
-For example, let's say we have several URLs that should only match when the
-host is "www.example.com". Create a route for that host and get a "subrouter"
-from it:
-
- r := mux.NewRouter()
- s := r.Host("www.example.com").Subrouter()
-
-Then register routes in the subrouter:
-
- s.HandleFunc("/products/", ProductsHandler)
- s.HandleFunc("/products/{key}", ProductHandler)
- s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
-
-The three URL paths we registered above will only be tested if the domain is
-"www.example.com", because the subrouter is tested first. This is not
-only convenient, but also optimizes request matching. You can create
-subrouters combining any attribute matchers accepted by a route.
-
-Subrouters can be used to create domain or path "namespaces": you define
-subrouters in a central place and then parts of the app can register its
-paths relatively to a given subrouter.
-
-There's one more thing about subroutes. When a subrouter has a path prefix,
-the inner routes use it as base for their paths:
-
- r := mux.NewRouter()
- s := r.PathPrefix("/products").Subrouter()
- // "/products/"
- s.HandleFunc("/", ProductsHandler)
- // "/products/{key}/"
- s.HandleFunc("/{key}/", ProductHandler)
- // "/products/{key}/details"
- s.HandleFunc("/{key}/details", ProductDetailsHandler)
-
-Now let's see how to build registered URLs.
-
-Routes can be named. All routes that define a name can have their URLs built,
-or "reversed". We define a name calling Name() on a route. For example:
-
- r := mux.NewRouter()
- r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
- Name("article")
-
-To build a URL, get the route and call the URL() method, passing a sequence of
-key/value pairs for the route variables. For the previous route, we would do:
-
- url, err := r.Get("article").URL("category", "technology", "id", "42")
-
-...and the result will be a url.URL with the following path:
-
- "/articles/technology/42"
-
-This also works for host variables:
-
- r := mux.NewRouter()
- r.Host("{subdomain}.domain.com").
- Path("/articles/{category}/{id:[0-9]+}").
- HandlerFunc(ArticleHandler).
- Name("article")
-
- // url.String() will be "http://news.domain.com/articles/technology/42"
- url, err := r.Get("article").URL("subdomain", "news",
- "category", "technology",
- "id", "42")
-
-All variables defined in the route are required, and their values must
-conform to the corresponding patterns. These requirements guarantee that a
-generated URL will always match a registered route -- the only exception is
-for explicitly defined "build-only" routes which never match.
-
-Regex support also exists for matching Headers within a route. For example, we could do:
-
- r.HeadersRegexp("Content-Type", "application/(text|json)")
-
-...and the route will match both requests with a Content-Type of `application/json` as well as
-`application/text`
-
-There's also a way to build only the URL host or path for a route:
-use the methods URLHost() or URLPath() instead. For the previous route,
-we would do:
-
- // "http://news.domain.com/"
- host, err := r.Get("article").URLHost("subdomain", "news")
-
- // "/articles/technology/42"
- path, err := r.Get("article").URLPath("category", "technology", "id", "42")
-
-And if you use subrouters, host and path defined separately can be built
-as well:
-
- r := mux.NewRouter()
- s := r.Host("{subdomain}.domain.com").Subrouter()
- s.Path("/articles/{category}/{id:[0-9]+}").
- HandlerFunc(ArticleHandler).
- Name("article")
-
- // "http://news.domain.com/articles/technology/42"
- url, err := r.Get("article").URL("subdomain", "news",
- "category", "technology",
- "id", "42")
-*/
-package mux
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/mux.go b/Godeps/_workspace/src/github.com/gorilla/mux/mux.go
deleted file mode 100644
index 68c4ea5d8..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/mux.go
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mux
-
-import (
- "errors"
- "fmt"
- "net/http"
- "path"
- "regexp"
-
- "github.com/gorilla/context"
-)
-
-// NewRouter returns a new router instance.
-func NewRouter() *Router {
- return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
-}
-
-// Router registers routes to be matched and dispatches a handler.
-//
-// It implements the http.Handler interface, so it can be registered to serve
-// requests:
-//
-// var router = mux.NewRouter()
-//
-// func main() {
-// http.Handle("/", router)
-// }
-//
-// Or, for Google App Engine, register it in a init() function:
-//
-// func init() {
-// http.Handle("/", router)
-// }
-//
-// This will send all incoming requests to the router.
-type Router struct {
- // Configurable Handler to be used when no route matches.
- NotFoundHandler http.Handler
- // Parent route, if this is a subrouter.
- parent parentRoute
- // Routes to be matched, in order.
- routes []*Route
- // Routes by name for URL building.
- namedRoutes map[string]*Route
- // See Router.StrictSlash(). This defines the flag for new routes.
- strictSlash bool
- // If true, do not clear the request context after handling the request
- KeepContext bool
-}
-
-// Match matches registered routes against the request.
-func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
- for _, route := range r.routes {
- if route.Match(req, match) {
- return true
- }
- }
- return false
-}
-
-// ServeHTTP dispatches the handler registered in the matched route.
-//
-// When there is a match, the route variables can be retrieved calling
-// mux.Vars(request).
-func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- // Clean path to canonical form and redirect.
- if p := cleanPath(req.URL.Path); p != req.URL.Path {
-
- // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
- // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
- // http://code.google.com/p/go/issues/detail?id=5252
- url := *req.URL
- url.Path = p
- p = url.String()
-
- w.Header().Set("Location", p)
- w.WriteHeader(http.StatusMovedPermanently)
- return
- }
- var match RouteMatch
- var handler http.Handler
- if r.Match(req, &match) {
- handler = match.Handler
- setVars(req, match.Vars)
- setCurrentRoute(req, match.Route)
- }
- if handler == nil {
- handler = r.NotFoundHandler
- if handler == nil {
- handler = http.NotFoundHandler()
- }
- }
- if !r.KeepContext {
- defer context.Clear(req)
- }
- handler.ServeHTTP(w, req)
-}
-
-// Get returns a route registered with the given name.
-func (r *Router) Get(name string) *Route {
- return r.getNamedRoutes()[name]
-}
-
-// GetRoute returns a route registered with the given name. This method
-// was renamed to Get() and remains here for backwards compatibility.
-func (r *Router) GetRoute(name string) *Route {
- return r.getNamedRoutes()[name]
-}
-
-// StrictSlash defines the trailing slash behavior for new routes. The initial
-// value is false.
-//
-// When true, if the route path is "/path/", accessing "/path" will redirect
-// to the former and vice versa. In other words, your application will always
-// see the path as specified in the route.
-//
-// When false, if the route path is "/path", accessing "/path/" will not match
-// this route and vice versa.
-//
-// Special case: when a route sets a path prefix using the PathPrefix() method,
-// strict slash is ignored for that route because the redirect behavior can't
-// be determined from a prefix alone. However, any subrouters created from that
-// route inherit the original StrictSlash setting.
-func (r *Router) StrictSlash(value bool) *Router {
- r.strictSlash = value
- return r
-}
-
-// ----------------------------------------------------------------------------
-// parentRoute
-// ----------------------------------------------------------------------------
-
-// getNamedRoutes returns the map where named routes are registered.
-func (r *Router) getNamedRoutes() map[string]*Route {
- if r.namedRoutes == nil {
- if r.parent != nil {
- r.namedRoutes = r.parent.getNamedRoutes()
- } else {
- r.namedRoutes = make(map[string]*Route)
- }
- }
- return r.namedRoutes
-}
-
-// getRegexpGroup returns regexp definitions from the parent route, if any.
-func (r *Router) getRegexpGroup() *routeRegexpGroup {
- if r.parent != nil {
- return r.parent.getRegexpGroup()
- }
- return nil
-}
-
-func (r *Router) buildVars(m map[string]string) map[string]string {
- if r.parent != nil {
- m = r.parent.buildVars(m)
- }
- return m
-}
-
-// ----------------------------------------------------------------------------
-// Route factories
-// ----------------------------------------------------------------------------
-
-// NewRoute registers an empty route.
-func (r *Router) NewRoute() *Route {
- route := &Route{parent: r, strictSlash: r.strictSlash}
- r.routes = append(r.routes, route)
- return route
-}
-
-// Handle registers a new route with a matcher for the URL path.
-// See Route.Path() and Route.Handler().
-func (r *Router) Handle(path string, handler http.Handler) *Route {
- return r.NewRoute().Path(path).Handler(handler)
-}
-
-// HandleFunc registers a new route with a matcher for the URL path.
-// See Route.Path() and Route.HandlerFunc().
-func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
- *http.Request)) *Route {
- return r.NewRoute().Path(path).HandlerFunc(f)
-}
-
-// Headers registers a new route with a matcher for request header values.
-// See Route.Headers().
-func (r *Router) Headers(pairs ...string) *Route {
- return r.NewRoute().Headers(pairs...)
-}
-
-// Host registers a new route with a matcher for the URL host.
-// See Route.Host().
-func (r *Router) Host(tpl string) *Route {
- return r.NewRoute().Host(tpl)
-}
-
-// MatcherFunc registers a new route with a custom matcher function.
-// See Route.MatcherFunc().
-func (r *Router) MatcherFunc(f MatcherFunc) *Route {
- return r.NewRoute().MatcherFunc(f)
-}
-
-// Methods registers a new route with a matcher for HTTP methods.
-// See Route.Methods().
-func (r *Router) Methods(methods ...string) *Route {
- return r.NewRoute().Methods(methods...)
-}
-
-// Path registers a new route with a matcher for the URL path.
-// See Route.Path().
-func (r *Router) Path(tpl string) *Route {
- return r.NewRoute().Path(tpl)
-}
-
-// PathPrefix registers a new route with a matcher for the URL path prefix.
-// See Route.PathPrefix().
-func (r *Router) PathPrefix(tpl string) *Route {
- return r.NewRoute().PathPrefix(tpl)
-}
-
-// Queries registers a new route with a matcher for URL query values.
-// See Route.Queries().
-func (r *Router) Queries(pairs ...string) *Route {
- return r.NewRoute().Queries(pairs...)
-}
-
-// Schemes registers a new route with a matcher for URL schemes.
-// See Route.Schemes().
-func (r *Router) Schemes(schemes ...string) *Route {
- return r.NewRoute().Schemes(schemes...)
-}
-
-// BuildVars registers a new route with a custom function for modifying
-// route variables before building a URL.
-func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
- return r.NewRoute().BuildVarsFunc(f)
-}
-
-// Walk walks the router and all its sub-routers, calling walkFn for each route
-// in the tree. The routes are walked in the order they were added. Sub-routers
-// are explored depth-first.
-func (r *Router) Walk(walkFn WalkFunc) error {
- return r.walk(walkFn, []*Route{})
-}
-
-// SkipRouter is used as a return value from WalkFuncs to indicate that the
-// router that walk is about to descend down to should be skipped.
-var SkipRouter = errors.New("skip this router")
-
-// WalkFunc is the type of the function called for each route visited by Walk.
-// At every invocation, it is given the current route, and the current router,
-// and a list of ancestor routes that lead to the current route.
-type WalkFunc func(route *Route, router *Router, ancestors []*Route) error
-
-func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
- for _, t := range r.routes {
- if t.regexp == nil || t.regexp.path == nil || t.regexp.path.template == "" {
- continue
- }
-
- err := walkFn(t, r, ancestors)
- if err == SkipRouter {
- continue
- }
- for _, sr := range t.matchers {
- if h, ok := sr.(*Router); ok {
- err := h.walk(walkFn, ancestors)
- if err != nil {
- return err
- }
- }
- }
- if h, ok := t.handler.(*Router); ok {
- ancestors = append(ancestors, t)
- err := h.walk(walkFn, ancestors)
- if err != nil {
- return err
- }
- ancestors = ancestors[:len(ancestors)-1]
- }
- }
- return nil
-}
-
-// ----------------------------------------------------------------------------
-// Context
-// ----------------------------------------------------------------------------
-
-// RouteMatch stores information about a matched route.
-type RouteMatch struct {
- Route *Route
- Handler http.Handler
- Vars map[string]string
-}
-
-type contextKey int
-
-const (
- varsKey contextKey = iota
- routeKey
-)
-
-// Vars returns the route variables for the current request, if any.
-func Vars(r *http.Request) map[string]string {
- if rv := context.Get(r, varsKey); rv != nil {
- return rv.(map[string]string)
- }
- return nil
-}
-
-// CurrentRoute returns the matched route for the current request, if any.
-// This only works when called inside the handler of the matched route
-// because the matched route is stored in the request context which is cleared
-// after the handler returns, unless the KeepContext option is set on the
-// Router.
-func CurrentRoute(r *http.Request) *Route {
- if rv := context.Get(r, routeKey); rv != nil {
- return rv.(*Route)
- }
- return nil
-}
-
-func setVars(r *http.Request, val interface{}) {
- context.Set(r, varsKey, val)
-}
-
-func setCurrentRoute(r *http.Request, val interface{}) {
- context.Set(r, routeKey, val)
-}
-
-// ----------------------------------------------------------------------------
-// Helpers
-// ----------------------------------------------------------------------------
-
-// cleanPath returns the canonical path for p, eliminating . and .. elements.
-// Borrowed from the net/http package.
-func cleanPath(p string) string {
- if p == "" {
- return "/"
- }
- if p[0] != '/' {
- p = "/" + p
- }
- np := path.Clean(p)
- // path.Clean removes trailing slash except for root;
- // put the trailing slash back if necessary.
- if p[len(p)-1] == '/' && np != "/" {
- np += "/"
- }
- return np
-}
-
-// uniqueVars returns an error if two slices contain duplicated strings.
-func uniqueVars(s1, s2 []string) error {
- for _, v1 := range s1 {
- for _, v2 := range s2 {
- if v1 == v2 {
- return fmt.Errorf("mux: duplicated route variable %q", v2)
- }
- }
- }
- return nil
-}
-
-// checkPairs returns the count of strings passed in, and an error if
-// the count is not an even number.
-func checkPairs(pairs ...string) (int, error) {
- length := len(pairs)
- if length%2 != 0 {
- return length, fmt.Errorf(
- "mux: number of parameters must be multiple of 2, got %v", pairs)
- }
- return length, nil
-}
-
-// mapFromPairsToString converts variadic string parameters to a
-// string to string map.
-func mapFromPairsToString(pairs ...string) (map[string]string, error) {
- length, err := checkPairs(pairs...)
- if err != nil {
- return nil, err
- }
- m := make(map[string]string, length/2)
- for i := 0; i < length; i += 2 {
- m[pairs[i]] = pairs[i+1]
- }
- return m, nil
-}
-
-// mapFromPairsToRegex converts variadic string paramers to a
-// string to regex map.
-func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) {
- length, err := checkPairs(pairs...)
- if err != nil {
- return nil, err
- }
- m := make(map[string]*regexp.Regexp, length/2)
- for i := 0; i < length; i += 2 {
- regex, err := regexp.Compile(pairs[i+1])
- if err != nil {
- return nil, err
- }
- m[pairs[i]] = regex
- }
- return m, nil
-}
-
-// matchInArray returns true if the given string value is in the array.
-func matchInArray(arr []string, value string) bool {
- for _, v := range arr {
- if v == value {
- return true
- }
- }
- return false
-}
-
-// matchMapWithString returns true if the given key/value pairs exist in a given map.
-func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool {
- for k, v := range toCheck {
- // Check if key exists.
- if canonicalKey {
- k = http.CanonicalHeaderKey(k)
- }
- if values := toMatch[k]; values == nil {
- return false
- } else if v != "" {
- // If value was defined as an empty string we only check that the
- // key exists. Otherwise we also check for equality.
- valueExists := false
- for _, value := range values {
- if v == value {
- valueExists = true
- break
- }
- }
- if !valueExists {
- return false
- }
- }
- }
- return true
-}
-
-// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against
-// the given regex
-func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool {
- for k, v := range toCheck {
- // Check if key exists.
- if canonicalKey {
- k = http.CanonicalHeaderKey(k)
- }
- if values := toMatch[k]; values == nil {
- return false
- } else if v != nil {
- // If value was defined as an empty string we only check that the
- // key exists. Otherwise we also check for equality.
- valueExists := false
- for _, value := range values {
- if v.MatchString(value) {
- valueExists = true
- break
- }
- }
- if !valueExists {
- return false
- }
- }
- }
- return true
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go b/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go
deleted file mode 100644
index 06728dd54..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mux
-
-import (
- "bytes"
- "fmt"
- "net/http"
- "net/url"
- "regexp"
- "strconv"
- "strings"
-)
-
-// newRouteRegexp parses a route template and returns a routeRegexp,
-// used to match a host, a path or a query string.
-//
-// It will extract named variables, assemble a regexp to be matched, create
-// a "reverse" template to build URLs and compile regexps to validate variable
-// values used in URL building.
-//
-// Previously we accepted only Python-like identifiers for variable
-// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that
-// name and pattern can't be empty, and names can't contain a colon.
-func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash bool) (*routeRegexp, error) {
- // Check if it is well-formed.
- idxs, errBraces := braceIndices(tpl)
- if errBraces != nil {
- return nil, errBraces
- }
- // Backup the original.
- template := tpl
- // Now let's parse it.
- defaultPattern := "[^/]+"
- if matchQuery {
- defaultPattern = "[^?&]*"
- } else if matchHost {
- defaultPattern = "[^.]+"
- matchPrefix = false
- }
- // Only match strict slash if not matching
- if matchPrefix || matchHost || matchQuery {
- strictSlash = false
- }
- // Set a flag for strictSlash.
- endSlash := false
- if strictSlash && strings.HasSuffix(tpl, "/") {
- tpl = tpl[:len(tpl)-1]
- endSlash = true
- }
- varsN := make([]string, len(idxs)/2)
- varsR := make([]*regexp.Regexp, len(idxs)/2)
- pattern := bytes.NewBufferString("")
- pattern.WriteByte('^')
- reverse := bytes.NewBufferString("")
- var end int
- var err error
- for i := 0; i < len(idxs); i += 2 {
- // Set all values we are interested in.
- raw := tpl[end:idxs[i]]
- end = idxs[i+1]
- parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2)
- name := parts[0]
- patt := defaultPattern
- if len(parts) == 2 {
- patt = parts[1]
- }
- // Name or pattern can't be empty.
- if name == "" || patt == "" {
- return nil, fmt.Errorf("mux: missing name or pattern in %q",
- tpl[idxs[i]:end])
- }
- // Build the regexp pattern.
- varIdx := i / 2
- fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(varIdx), patt)
- // Build the reverse template.
- fmt.Fprintf(reverse, "%s%%s", raw)
-
- // Append variable name and compiled pattern.
- varsN[varIdx] = name
- varsR[varIdx], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
- if err != nil {
- return nil, err
- }
- }
- // Add the remaining.
- raw := tpl[end:]
- pattern.WriteString(regexp.QuoteMeta(raw))
- if strictSlash {
- pattern.WriteString("[/]?")
- }
- if matchQuery {
- // Add the default pattern if the query value is empty
- if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" {
- pattern.WriteString(defaultPattern)
- }
- }
- if !matchPrefix {
- pattern.WriteByte('$')
- }
- reverse.WriteString(raw)
- if endSlash {
- reverse.WriteByte('/')
- }
- // Compile full regexp.
- reg, errCompile := regexp.Compile(pattern.String())
- if errCompile != nil {
- return nil, errCompile
- }
- // Done!
- return &routeRegexp{
- template: template,
- matchHost: matchHost,
- matchQuery: matchQuery,
- strictSlash: strictSlash,
- regexp: reg,
- reverse: reverse.String(),
- varsN: varsN,
- varsR: varsR,
- }, nil
-}
-
-// routeRegexp stores a regexp to match a host or path and information to
-// collect and validate route variables.
-type routeRegexp struct {
- // The unmodified template.
- template string
- // True for host match, false for path or query string match.
- matchHost bool
- // True for query string match, false for path and host match.
- matchQuery bool
- // The strictSlash value defined on the route, but disabled if PathPrefix was used.
- strictSlash bool
- // Expanded regexp.
- regexp *regexp.Regexp
- // Reverse template.
- reverse string
- // Variable names.
- varsN []string
- // Variable regexps (validators).
- varsR []*regexp.Regexp
-}
-
-// Match matches the regexp against the URL host or path.
-func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
- if !r.matchHost {
- if r.matchQuery {
- return r.matchQueryString(req)
- } else {
- return r.regexp.MatchString(req.URL.Path)
- }
- }
- return r.regexp.MatchString(getHost(req))
-}
-
-// url builds a URL part using the given values.
-func (r *routeRegexp) url(values map[string]string) (string, error) {
- urlValues := make([]interface{}, len(r.varsN))
- for k, v := range r.varsN {
- value, ok := values[v]
- if !ok {
- return "", fmt.Errorf("mux: missing route variable %q", v)
- }
- urlValues[k] = value
- }
- rv := fmt.Sprintf(r.reverse, urlValues...)
- if !r.regexp.MatchString(rv) {
- // The URL is checked against the full regexp, instead of checking
- // individual variables. This is faster but to provide a good error
- // message, we check individual regexps if the URL doesn't match.
- for k, v := range r.varsN {
- if !r.varsR[k].MatchString(values[v]) {
- return "", fmt.Errorf(
- "mux: variable %q doesn't match, expected %q", values[v],
- r.varsR[k].String())
- }
- }
- }
- return rv, nil
-}
-
-// getUrlQuery returns a single query parameter from a request URL.
-// For a URL with foo=bar&baz=ding, we return only the relevant key
-// value pair for the routeRegexp.
-func (r *routeRegexp) getUrlQuery(req *http.Request) string {
- if !r.matchQuery {
- return ""
- }
- templateKey := strings.SplitN(r.template, "=", 2)[0]
- for key, vals := range req.URL.Query() {
- if key == templateKey && len(vals) > 0 {
- return key + "=" + vals[0]
- }
- }
- return ""
-}
-
-func (r *routeRegexp) matchQueryString(req *http.Request) bool {
- return r.regexp.MatchString(r.getUrlQuery(req))
-}
-
-// braceIndices returns the first level curly brace indices from a string.
-// It returns an error in case of unbalanced braces.
-func braceIndices(s string) ([]int, error) {
- var level, idx int
- idxs := make([]int, 0)
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '{':
- if level++; level == 1 {
- idx = i
- }
- case '}':
- if level--; level == 0 {
- idxs = append(idxs, idx, i+1)
- } else if level < 0 {
- return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
- }
- }
- }
- if level != 0 {
- return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
- }
- return idxs, nil
-}
-
-// varGroupName builds a capturing group name for the indexed variable.
-func varGroupName(idx int) string {
- return "v" + strconv.Itoa(idx)
-}
-
-// ----------------------------------------------------------------------------
-// routeRegexpGroup
-// ----------------------------------------------------------------------------
-
-// routeRegexpGroup groups the route matchers that carry variables.
-type routeRegexpGroup struct {
- host *routeRegexp
- path *routeRegexp
- queries []*routeRegexp
-}
-
-// setMatch extracts the variables from the URL once a route matches.
-func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
- // Store host variables.
- if v.host != nil {
- hostVars := v.host.regexp.FindStringSubmatch(getHost(req))
- if hostVars != nil {
- subexpNames := v.host.regexp.SubexpNames()
- varName := 0
- for i, name := range subexpNames[1:] {
- if name != "" && name == varGroupName(varName) {
- m.Vars[v.host.varsN[varName]] = hostVars[i+1]
- varName++
- }
- }
- }
- }
- // Store path variables.
- if v.path != nil {
- pathVars := v.path.regexp.FindStringSubmatch(req.URL.Path)
- if pathVars != nil {
- subexpNames := v.path.regexp.SubexpNames()
- varName := 0
- for i, name := range subexpNames[1:] {
- if name != "" && name == varGroupName(varName) {
- m.Vars[v.path.varsN[varName]] = pathVars[i+1]
- varName++
- }
- }
- // Check if we should redirect.
- if v.path.strictSlash {
- p1 := strings.HasSuffix(req.URL.Path, "/")
- p2 := strings.HasSuffix(v.path.template, "/")
- if p1 != p2 {
- u, _ := url.Parse(req.URL.String())
- if p1 {
- u.Path = u.Path[:len(u.Path)-1]
- } else {
- u.Path += "/"
- }
- m.Handler = http.RedirectHandler(u.String(), 301)
- }
- }
- }
- }
- // Store query string variables.
- for _, q := range v.queries {
- queryVars := q.regexp.FindStringSubmatch(q.getUrlQuery(req))
- if queryVars != nil {
- subexpNames := q.regexp.SubexpNames()
- varName := 0
- for i, name := range subexpNames[1:] {
- if name != "" && name == varGroupName(varName) {
- m.Vars[q.varsN[varName]] = queryVars[i+1]
- varName++
- }
- }
- }
- }
-}
-
-// getHost tries its best to return the request host.
-func getHost(r *http.Request) string {
- if r.URL.IsAbs() {
- return r.URL.Host
- }
- host := r.Host
- // Slice off any port information.
- if i := strings.Index(host, ":"); i != -1 {
- host = host[:i]
- }
- return host
-
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/route.go b/Godeps/_workspace/src/github.com/gorilla/mux/route.go
deleted file mode 100644
index 913432c1c..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/mux/route.go
+++ /dev/null
@@ -1,595 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mux
-
-import (
- "errors"
- "fmt"
- "net/http"
- "net/url"
- "regexp"
- "strings"
-)
-
-// Route stores information to match a request and build URLs.
-type Route struct {
- // Parent where the route was registered (a Router).
- parent parentRoute
- // Request handler for the route.
- handler http.Handler
- // List of matchers.
- matchers []matcher
- // Manager for the variables from host and path.
- regexp *routeRegexpGroup
- // If true, when the path pattern is "/path/", accessing "/path" will
- // redirect to the former and vice versa.
- strictSlash bool
- // If true, this route never matches: it is only used to build URLs.
- buildOnly bool
- // The name used to build URLs.
- name string
- // Error resulted from building a route.
- err error
-
- buildVarsFunc BuildVarsFunc
-}
-
-// Match matches the route against the request.
-func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
- if r.buildOnly || r.err != nil {
- return false
- }
- // Match everything.
- for _, m := range r.matchers {
- if matched := m.Match(req, match); !matched {
- return false
- }
- }
- // Yay, we have a match. Let's collect some info about it.
- if match.Route == nil {
- match.Route = r
- }
- if match.Handler == nil {
- match.Handler = r.handler
- }
- if match.Vars == nil {
- match.Vars = make(map[string]string)
- }
- // Set variables.
- if r.regexp != nil {
- r.regexp.setMatch(req, match, r)
- }
- return true
-}
-
-// ----------------------------------------------------------------------------
-// Route attributes
-// ----------------------------------------------------------------------------
-
-// GetError returns an error resulted from building the route, if any.
-func (r *Route) GetError() error {
- return r.err
-}
-
-// BuildOnly sets the route to never match: it is only used to build URLs.
-func (r *Route) BuildOnly() *Route {
- r.buildOnly = true
- return r
-}
-
-// Handler --------------------------------------------------------------------
-
-// Handler sets a handler for the route.
-func (r *Route) Handler(handler http.Handler) *Route {
- if r.err == nil {
- r.handler = handler
- }
- return r
-}
-
-// HandlerFunc sets a handler function for the route.
-func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route {
- return r.Handler(http.HandlerFunc(f))
-}
-
-// GetHandler returns the handler for the route, if any.
-func (r *Route) GetHandler() http.Handler {
- return r.handler
-}
-
-// Name -----------------------------------------------------------------------
-
-// Name sets the name for the route, used to build URLs.
-// If the name was registered already it will be overwritten.
-func (r *Route) Name(name string) *Route {
- if r.name != "" {
- r.err = fmt.Errorf("mux: route already has name %q, can't set %q",
- r.name, name)
- }
- if r.err == nil {
- r.name = name
- r.getNamedRoutes()[name] = r
- }
- return r
-}
-
-// GetName returns the name for the route, if any.
-func (r *Route) GetName() string {
- return r.name
-}
-
-// ----------------------------------------------------------------------------
-// Matchers
-// ----------------------------------------------------------------------------
-
-// matcher types try to match a request.
-type matcher interface {
- Match(*http.Request, *RouteMatch) bool
-}
-
-// addMatcher adds a matcher to the route.
-func (r *Route) addMatcher(m matcher) *Route {
- if r.err == nil {
- r.matchers = append(r.matchers, m)
- }
- return r
-}
-
-// addRegexpMatcher adds a host or path matcher and builder to a route.
-func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error {
- if r.err != nil {
- return r.err
- }
- r.regexp = r.getRegexpGroup()
- if !matchHost && !matchQuery {
- if len(tpl) == 0 || tpl[0] != '/' {
- return fmt.Errorf("mux: path must start with a slash, got %q", tpl)
- }
- if r.regexp.path != nil {
- tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl
- }
- }
- rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash)
- if err != nil {
- return err
- }
- for _, q := range r.regexp.queries {
- if err = uniqueVars(rr.varsN, q.varsN); err != nil {
- return err
- }
- }
- if matchHost {
- if r.regexp.path != nil {
- if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil {
- return err
- }
- }
- r.regexp.host = rr
- } else {
- if r.regexp.host != nil {
- if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil {
- return err
- }
- }
- if matchQuery {
- r.regexp.queries = append(r.regexp.queries, rr)
- } else {
- r.regexp.path = rr
- }
- }
- r.addMatcher(rr)
- return nil
-}
-
-// Headers --------------------------------------------------------------------
-
-// headerMatcher matches the request against header values.
-type headerMatcher map[string]string
-
-func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
- return matchMapWithString(m, r.Header, true)
-}
-
-// Headers adds a matcher for request header values.
-// It accepts a sequence of key/value pairs to be matched. For example:
-//
-// r := mux.NewRouter()
-// r.Headers("Content-Type", "application/json",
-// "X-Requested-With", "XMLHttpRequest")
-//
-// The above route will only match if both request header values match.
-// If the value is an empty string, it will match any value if the key is set.
-func (r *Route) Headers(pairs ...string) *Route {
- if r.err == nil {
- var headers map[string]string
- headers, r.err = mapFromPairsToString(pairs...)
- return r.addMatcher(headerMatcher(headers))
- }
- return r
-}
-
-// headerRegexMatcher matches the request against the route given a regex for the header
-type headerRegexMatcher map[string]*regexp.Regexp
-
-func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool {
- return matchMapWithRegex(m, r.Header, true)
-}
-
-// Regular expressions can be used with headers as well.
-// It accepts a sequence of key/value pairs, where the value has regex support. For example
-// r := mux.NewRouter()
-// r.HeadersRegexp("Content-Type", "application/(text|json)",
-// "X-Requested-With", "XMLHttpRequest")
-//
-// The above route will only match if both the request header matches both regular expressions.
-// It the value is an empty string, it will match any value if the key is set.
-func (r *Route) HeadersRegexp(pairs ...string) *Route {
- if r.err == nil {
- var headers map[string]*regexp.Regexp
- headers, r.err = mapFromPairsToRegex(pairs...)
- return r.addMatcher(headerRegexMatcher(headers))
- }
- return r
-}
-
-// Host -----------------------------------------------------------------------
-
-// Host adds a matcher for the URL host.
-// It accepts a template with zero or more URL variables enclosed by {}.
-// Variables can define an optional regexp pattern to be matched:
-//
-// - {name} matches anything until the next dot.
-//
-// - {name:pattern} matches the given regexp pattern.
-//
-// For example:
-//
-// r := mux.NewRouter()
-// r.Host("www.example.com")
-// r.Host("{subdomain}.domain.com")
-// r.Host("{subdomain:[a-z]+}.domain.com")
-//
-// Variable names must be unique in a given route. They can be retrieved
-// calling mux.Vars(request).
-func (r *Route) Host(tpl string) *Route {
- r.err = r.addRegexpMatcher(tpl, true, false, false)
- return r
-}
-
-// MatcherFunc ----------------------------------------------------------------
-
-// MatcherFunc is the function signature used by custom matchers.
-type MatcherFunc func(*http.Request, *RouteMatch) bool
-
-func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
- return m(r, match)
-}
-
-// MatcherFunc adds a custom function to be used as request matcher.
-func (r *Route) MatcherFunc(f MatcherFunc) *Route {
- return r.addMatcher(f)
-}
-
-// Methods --------------------------------------------------------------------
-
-// methodMatcher matches the request against HTTP methods.
-type methodMatcher []string
-
-func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool {
- return matchInArray(m, r.Method)
-}
-
-// Methods adds a matcher for HTTP methods.
-// It accepts a sequence of one or more methods to be matched, e.g.:
-// "GET", "POST", "PUT".
-func (r *Route) Methods(methods ...string) *Route {
- for k, v := range methods {
- methods[k] = strings.ToUpper(v)
- }
- return r.addMatcher(methodMatcher(methods))
-}
-
-// Path -----------------------------------------------------------------------
-
-// Path adds a matcher for the URL path.
-// It accepts a template with zero or more URL variables enclosed by {}. The
-// template must start with a "/".
-// Variables can define an optional regexp pattern to be matched:
-//
-// - {name} matches anything until the next slash.
-//
-// - {name:pattern} matches the given regexp pattern.
-//
-// For example:
-//
-// r := mux.NewRouter()
-// r.Path("/products/").Handler(ProductsHandler)
-// r.Path("/products/{key}").Handler(ProductsHandler)
-// r.Path("/articles/{category}/{id:[0-9]+}").
-// Handler(ArticleHandler)
-//
-// Variable names must be unique in a given route. They can be retrieved
-// calling mux.Vars(request).
-func (r *Route) Path(tpl string) *Route {
- r.err = r.addRegexpMatcher(tpl, false, false, false)
- return r
-}
-
-// PathPrefix -----------------------------------------------------------------
-
-// PathPrefix adds a matcher for the URL path prefix. This matches if the given
-// template is a prefix of the full URL path. See Route.Path() for details on
-// the tpl argument.
-//
-// Note that it does not treat slashes specially ("/foobar/" will be matched by
-// the prefix "/foo") so you may want to use a trailing slash here.
-//
-// Also note that the setting of Router.StrictSlash() has no effect on routes
-// with a PathPrefix matcher.
-func (r *Route) PathPrefix(tpl string) *Route {
- r.err = r.addRegexpMatcher(tpl, false, true, false)
- return r
-}
-
-// Query ----------------------------------------------------------------------
-
-// Queries adds a matcher for URL query values.
-// It accepts a sequence of key/value pairs. Values may define variables.
-// For example:
-//
-// r := mux.NewRouter()
-// r.Queries("foo", "bar", "id", "{id:[0-9]+}")
-//
-// The above route will only match if the URL contains the defined queries
-// values, e.g.: ?foo=bar&id=42.
-//
-// It the value is an empty string, it will match any value if the key is set.
-//
-// Variables can define an optional regexp pattern to be matched:
-//
-// - {name} matches anything until the next slash.
-//
-// - {name:pattern} matches the given regexp pattern.
-func (r *Route) Queries(pairs ...string) *Route {
- length := len(pairs)
- if length%2 != 0 {
- r.err = fmt.Errorf(
- "mux: number of parameters must be multiple of 2, got %v", pairs)
- return nil
- }
- for i := 0; i < length; i += 2 {
- if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil {
- return r
- }
- }
-
- return r
-}
-
-// Schemes --------------------------------------------------------------------
-
-// schemeMatcher matches the request against URL schemes.
-type schemeMatcher []string
-
-func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
- return matchInArray(m, r.URL.Scheme)
-}
-
-// Schemes adds a matcher for URL schemes.
-// It accepts a sequence of schemes to be matched, e.g.: "http", "https".
-func (r *Route) Schemes(schemes ...string) *Route {
- for k, v := range schemes {
- schemes[k] = strings.ToLower(v)
- }
- return r.addMatcher(schemeMatcher(schemes))
-}
-
-// BuildVarsFunc --------------------------------------------------------------
-
-// BuildVarsFunc is the function signature used by custom build variable
-// functions (which can modify route variables before a route's URL is built).
-type BuildVarsFunc func(map[string]string) map[string]string
-
-// BuildVarsFunc adds a custom function to be used to modify build variables
-// before a route's URL is built.
-func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
- r.buildVarsFunc = f
- return r
-}
-
-// Subrouter ------------------------------------------------------------------
-
-// Subrouter creates a subrouter for the route.
-//
-// It will test the inner routes only if the parent route matched. For example:
-//
-// r := mux.NewRouter()
-// s := r.Host("www.example.com").Subrouter()
-// s.HandleFunc("/products/", ProductsHandler)
-// s.HandleFunc("/products/{key}", ProductHandler)
-// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
-//
-// Here, the routes registered in the subrouter won't be tested if the host
-// doesn't match.
-func (r *Route) Subrouter() *Router {
- router := &Router{parent: r, strictSlash: r.strictSlash}
- r.addMatcher(router)
- return router
-}
-
-// ----------------------------------------------------------------------------
-// URL building
-// ----------------------------------------------------------------------------
-
-// URL builds a URL for the route.
-//
-// It accepts a sequence of key/value pairs for the route variables. For
-// example, given this route:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
-// Name("article")
-//
-// ...a URL for it can be built using:
-//
-// url, err := r.Get("article").URL("category", "technology", "id", "42")
-//
-// ...which will return an url.URL with the following path:
-//
-// "/articles/technology/42"
-//
-// This also works for host variables:
-//
-// r := mux.NewRouter()
-// r.Host("{subdomain}.domain.com").
-// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
-// Name("article")
-//
-// // url.String() will be "http://news.domain.com/articles/technology/42"
-// url, err := r.Get("article").URL("subdomain", "news",
-// "category", "technology",
-// "id", "42")
-//
-// All variables defined in the route are required, and their values must
-// conform to the corresponding patterns.
-func (r *Route) URL(pairs ...string) (*url.URL, error) {
- if r.err != nil {
- return nil, r.err
- }
- if r.regexp == nil {
- return nil, errors.New("mux: route doesn't have a host or path")
- }
- values, err := r.prepareVars(pairs...)
- if err != nil {
- return nil, err
- }
- var scheme, host, path string
- if r.regexp.host != nil {
- // Set a default scheme.
- scheme = "http"
- if host, err = r.regexp.host.url(values); err != nil {
- return nil, err
- }
- }
- if r.regexp.path != nil {
- if path, err = r.regexp.path.url(values); err != nil {
- return nil, err
- }
- }
- return &url.URL{
- Scheme: scheme,
- Host: host,
- Path: path,
- }, nil
-}
-
-// URLHost builds the host part of the URL for a route. See Route.URL().
-//
-// The route must have a host defined.
-func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
- if r.err != nil {
- return nil, r.err
- }
- if r.regexp == nil || r.regexp.host == nil {
- return nil, errors.New("mux: route doesn't have a host")
- }
- values, err := r.prepareVars(pairs...)
- if err != nil {
- return nil, err
- }
- host, err := r.regexp.host.url(values)
- if err != nil {
- return nil, err
- }
- return &url.URL{
- Scheme: "http",
- Host: host,
- }, nil
-}
-
-// URLPath builds the path part of the URL for a route. See Route.URL().
-//
-// The route must have a path defined.
-func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
- if r.err != nil {
- return nil, r.err
- }
- if r.regexp == nil || r.regexp.path == nil {
- return nil, errors.New("mux: route doesn't have a path")
- }
- values, err := r.prepareVars(pairs...)
- if err != nil {
- return nil, err
- }
- path, err := r.regexp.path.url(values)
- if err != nil {
- return nil, err
- }
- return &url.URL{
- Path: path,
- }, nil
-}
-
-// prepareVars converts the route variable pairs into a map. If the route has a
-// BuildVarsFunc, it is invoked.
-func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
- m, err := mapFromPairsToString(pairs...)
- if err != nil {
- return nil, err
- }
- return r.buildVars(m), nil
-}
-
-func (r *Route) buildVars(m map[string]string) map[string]string {
- if r.parent != nil {
- m = r.parent.buildVars(m)
- }
- if r.buildVarsFunc != nil {
- m = r.buildVarsFunc(m)
- }
- return m
-}
-
-// ----------------------------------------------------------------------------
-// parentRoute
-// ----------------------------------------------------------------------------
-
-// parentRoute allows routes to know about parent host and path definitions.
-type parentRoute interface {
- getNamedRoutes() map[string]*Route
- getRegexpGroup() *routeRegexpGroup
- buildVars(map[string]string) map[string]string
-}
-
-// getNamedRoutes returns the map where named routes are registered.
-func (r *Route) getNamedRoutes() map[string]*Route {
- if r.parent == nil {
- // During tests router is not always set.
- r.parent = NewRouter()
- }
- return r.parent.getNamedRoutes()
-}
-
-// getRegexpGroup returns regexp definitions from this route.
-func (r *Route) getRegexpGroup() *routeRegexpGroup {
- if r.regexp == nil {
- if r.parent == nil {
- // During tests router is not always set.
- r.parent = NewRouter()
- }
- regexp := r.parent.getRegexpGroup()
- if regexp == nil {
- r.regexp = new(routeRegexpGroup)
- } else {
- // Copy.
- r.regexp = &routeRegexpGroup{
- host: regexp.host,
- path: regexp.path,
- queries: regexp.queries,
- }
- }
- }
- return r.regexp
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore b/Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore
deleted file mode 100644
index 00268614f..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml b/Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml
deleted file mode 100644
index 8687342e9..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: go
-
-go:
- - 1.1
- - 1.2
- - tip
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS b/Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS
deleted file mode 100644
index b003eca0c..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS
+++ /dev/null
@@ -1,8 +0,0 @@
-# This is the official list of Gorilla WebSocket authors for copyright
-# purposes.
-#
-# Please keep the list sorted.
-
-Gary Burd <gary@beagledreams.com>
-Joachim Bauch <mail@joachim-bauch.de>
-
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE b/Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE
deleted file mode 100644
index 9171c9722..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
deleted file mode 100644
index 9d71959ea..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Gorilla WebSocket
-
-Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
-[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
-
-### Documentation
-
-* [API Reference](http://godoc.org/github.com/gorilla/websocket)
-* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
-* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
-* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
-* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
-
-### Status
-
-The Gorilla WebSocket package provides a complete and tested implementation of
-the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
-package API is stable.
-
-### Installation
-
- go get github.com/gorilla/websocket
-
-### Protocol Compliance
-
-The Gorilla WebSocket package passes the server tests in the [Autobahn Test
-Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
-subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
-
-### Gorilla WebSocket compared with other packages
-
-<table>
-<tr>
-<th></th>
-<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
-<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
-</tr>
-<tr>
-<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
-<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
-<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
-<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
-<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
-<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
-<tr><td colspan="3">Other Features</tr></td>
-<tr><td>Limit size of received message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.SetReadLimit">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=5082">No</a></td></tr>
-<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
-<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
-</table>
-
-Notes:
-
-1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
-2. The application can get the type of a received data message by implementing
- a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
- function.
-3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
- Read returns when the input buffer is full or a frame boundary is
- encountered. Each call to Write sends a single frame message. The Gorilla
- io.Reader and io.WriteCloser operate on a single WebSocket message.
-
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/client.go b/Godeps/_workspace/src/github.com/gorilla/websocket/client.go
deleted file mode 100644
index 613890603..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/client.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bufio"
- "bytes"
- "crypto/tls"
- "errors"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/url"
- "strings"
- "time"
-)
-
-// ErrBadHandshake is returned when the server response to opening handshake is
-// invalid.
-var ErrBadHandshake = errors.New("websocket: bad handshake")
-
-// NewClient creates a new client connection using the given net connection.
-// The URL u specifies the host and request URI. Use requestHeader to specify
-// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
-// (Cookie). Use the response.Header to get the selected subprotocol
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etc.
-//
-// Deprecated: Use Dialer instead.
-func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
- d := Dialer{
- ReadBufferSize: readBufSize,
- WriteBufferSize: writeBufSize,
- NetDial: func(net, addr string) (net.Conn, error) {
- return netConn, nil
- },
- }
- return d.Dial(u.String(), requestHeader)
-}
-
-// A Dialer contains options for connecting to WebSocket server.
-type Dialer struct {
- // NetDial specifies the dial function for creating TCP connections. If
- // NetDial is nil, net.Dial is used.
- NetDial func(network, addr string) (net.Conn, error)
-
- // Proxy specifies a function to return a proxy for a given
- // Request. If the function returns a non-nil error, the
- // request is aborted with the provided error.
- // If Proxy is nil or returns a nil *URL, no proxy is used.
- Proxy func(*http.Request) (*url.URL, error)
-
- // TLSClientConfig specifies the TLS configuration to use with tls.Client.
- // If nil, the default configuration is used.
- TLSClientConfig *tls.Config
-
- // HandshakeTimeout specifies the duration for the handshake to complete.
- HandshakeTimeout time.Duration
-
- // Input and output buffer sizes. If the buffer size is zero, then a
- // default value of 4096 is used.
- ReadBufferSize, WriteBufferSize int
-
- // Subprotocols specifies the client's requested subprotocols.
- Subprotocols []string
-}
-
-var errMalformedURL = errors.New("malformed ws or wss URL")
-
-// parseURL parses the URL.
-//
-// This function is a replacement for the standard library url.Parse function.
-// In Go 1.4 and earlier, url.Parse loses information from the path.
-func parseURL(s string) (*url.URL, error) {
- // From the RFC:
- //
- // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
- // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
-
- var u url.URL
- switch {
- case strings.HasPrefix(s, "ws://"):
- u.Scheme = "ws"
- s = s[len("ws://"):]
- case strings.HasPrefix(s, "wss://"):
- u.Scheme = "wss"
- s = s[len("wss://"):]
- default:
- return nil, errMalformedURL
- }
-
- if i := strings.Index(s, "?"); i >= 0 {
- u.RawQuery = s[i+1:]
- s = s[:i]
- }
-
- if i := strings.Index(s, "/"); i >= 0 {
- u.Opaque = s[i:]
- s = s[:i]
- } else {
- u.Opaque = "/"
- }
-
- u.Host = s
-
- if strings.Contains(u.Host, "@") {
- // Don't bother parsing user information because user information is
- // not allowed in websocket URIs.
- return nil, errMalformedURL
- }
-
- return &u, nil
-}
-
-func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
- hostPort = u.Host
- hostNoPort = u.Host
- if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
- hostNoPort = hostNoPort[:i]
- } else {
- switch u.Scheme {
- case "wss":
- hostPort += ":443"
- case "https":
- hostPort += ":443"
- default:
- hostPort += ":80"
- }
- }
- return hostPort, hostNoPort
-}
-
-// DefaultDialer is a dialer with all fields set to the default zero values.
-var DefaultDialer = &Dialer{
- Proxy: http.ProxyFromEnvironment,
-}
-
-// Dial creates a new client connection. Use requestHeader to specify the
-// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
-// Use the response.Header to get the selected subprotocol
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etcetera. The response body may not contain the entire response and does not
-// need to be closed by the application.
-func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
-
- if d == nil {
- d = &Dialer{
- Proxy: http.ProxyFromEnvironment,
- }
- }
-
- challengeKey, err := generateChallengeKey()
- if err != nil {
- return nil, nil, err
- }
-
- u, err := parseURL(urlStr)
- if err != nil {
- return nil, nil, err
- }
-
- switch u.Scheme {
- case "ws":
- u.Scheme = "http"
- case "wss":
- u.Scheme = "https"
- default:
- return nil, nil, errMalformedURL
- }
-
- if u.User != nil {
- // User name and password are not allowed in websocket URIs.
- return nil, nil, errMalformedURL
- }
-
- req := &http.Request{
- Method: "GET",
- URL: u,
- Proto: "HTTP/1.1",
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: make(http.Header),
- Host: u.Host,
- }
-
- // Set the request headers using the capitalization for names and values in
- // RFC examples. Although the capitalization shouldn't matter, there are
- // servers that depend on it. The Header.Set method is not used because the
- // method canonicalizes the header names.
- req.Header["Upgrade"] = []string{"websocket"}
- req.Header["Connection"] = []string{"Upgrade"}
- req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
- req.Header["Sec-WebSocket-Version"] = []string{"13"}
- if len(d.Subprotocols) > 0 {
- req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
- }
- for k, vs := range requestHeader {
- switch {
- case k == "Host":
- if len(vs) > 0 {
- req.Host = vs[0]
- }
- case k == "Upgrade" ||
- k == "Connection" ||
- k == "Sec-Websocket-Key" ||
- k == "Sec-Websocket-Version" ||
- (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
- return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
- default:
- req.Header[k] = vs
- }
- }
-
- hostPort, hostNoPort := hostPortNoPort(u)
-
- var proxyURL *url.URL
- // Check wether the proxy method has been configured
- if d.Proxy != nil {
- proxyURL, err = d.Proxy(req)
- }
- if err != nil {
- return nil, nil, err
- }
-
- var targetHostPort string
- if proxyURL != nil {
- targetHostPort, _ = hostPortNoPort(proxyURL)
- } else {
- targetHostPort = hostPort
- }
-
- var deadline time.Time
- if d.HandshakeTimeout != 0 {
- deadline = time.Now().Add(d.HandshakeTimeout)
- }
-
- netDial := d.NetDial
- if netDial == nil {
- netDialer := &net.Dialer{Deadline: deadline}
- netDial = netDialer.Dial
- }
-
- netConn, err := netDial("tcp", targetHostPort)
- if err != nil {
- return nil, nil, err
- }
-
- defer func() {
- if netConn != nil {
- netConn.Close()
- }
- }()
-
- if err := netConn.SetDeadline(deadline); err != nil {
- return nil, nil, err
- }
-
- if proxyURL != nil {
- connectReq := &http.Request{
- Method: "CONNECT",
- URL: &url.URL{Opaque: hostPort},
- Host: hostPort,
- Header: make(http.Header),
- }
-
- connectReq.Write(netConn)
-
- // Read response.
- // Okay to use and discard buffered reader here, because
- // TLS server will not speak until spoken to.
- br := bufio.NewReader(netConn)
- resp, err := http.ReadResponse(br, connectReq)
- if err != nil {
- return nil, nil, err
- }
- if resp.StatusCode != 200 {
- f := strings.SplitN(resp.Status, " ", 2)
- return nil, nil, errors.New(f[1])
- }
- }
-
- if u.Scheme == "https" {
- cfg := d.TLSClientConfig
- if cfg == nil {
- cfg = &tls.Config{ServerName: hostNoPort}
- } else if cfg.ServerName == "" {
- shallowCopy := *cfg
- cfg = &shallowCopy
- cfg.ServerName = hostNoPort
- }
- tlsConn := tls.Client(netConn, cfg)
- netConn = tlsConn
- if err := tlsConn.Handshake(); err != nil {
- return nil, nil, err
- }
- if !cfg.InsecureSkipVerify {
- if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
- return nil, nil, err
- }
- }
- }
-
- conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize)
-
- if err := req.Write(netConn); err != nil {
- return nil, nil, err
- }
-
- resp, err := http.ReadResponse(conn.br, req)
- if err != nil {
- return nil, nil, err
- }
- if resp.StatusCode != 101 ||
- !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
- !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
- resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
- // Before closing the network connection on return from this
- // function, slurp up some of the response to aid application
- // debugging.
- buf := make([]byte, 1024)
- n, _ := io.ReadFull(resp.Body, buf)
- resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
- return nil, resp, ErrBadHandshake
- }
-
- resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
- conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
-
- netConn.SetDeadline(time.Time{})
- netConn = nil // to avoid close in defer.
- return conn, resp, nil
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
deleted file mode 100644
index e8b6b3e04..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
+++ /dev/null
@@ -1,831 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bufio"
- "encoding/binary"
- "errors"
- "io"
- "io/ioutil"
- "math/rand"
- "net"
- "strconv"
- "time"
-)
-
-const (
- maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
- maxControlFramePayloadSize = 125
- finalBit = 1 << 7
- maskBit = 1 << 7
- writeWait = time.Second
-
- defaultReadBufferSize = 4096
- defaultWriteBufferSize = 4096
-
- continuationFrame = 0
- noFrame = -1
-)
-
-// Close codes defined in RFC 6455, section 11.7.
-const (
- CloseNormalClosure = 1000
- CloseGoingAway = 1001
- CloseProtocolError = 1002
- CloseUnsupportedData = 1003
- CloseNoStatusReceived = 1005
- CloseAbnormalClosure = 1006
- CloseInvalidFramePayloadData = 1007
- ClosePolicyViolation = 1008
- CloseMessageTooBig = 1009
- CloseMandatoryExtension = 1010
- CloseInternalServerErr = 1011
- CloseTLSHandshake = 1015
-)
-
-// The message types are defined in RFC 6455, section 11.8.
-const (
- // TextMessage denotes a text data message. The text message payload is
- // interpreted as UTF-8 encoded text data.
- TextMessage = 1
-
- // BinaryMessage denotes a binary data message.
- BinaryMessage = 2
-
- // CloseMessage denotes a close control message. The optional message
- // payload contains a numeric code and text. Use the FormatCloseMessage
- // function to format a close message payload.
- CloseMessage = 8
-
- // PingMessage denotes a ping control message. The optional message payload
- // is UTF-8 encoded text.
- PingMessage = 9
-
- // PongMessage denotes a ping control message. The optional message payload
- // is UTF-8 encoded text.
- PongMessage = 10
-)
-
-// ErrCloseSent is returned when the application writes a message to the
-// connection after sending a close message.
-var ErrCloseSent = errors.New("websocket: close sent")
-
-// ErrReadLimit is returned when reading a message that is larger than the
-// read limit set for the connection.
-var ErrReadLimit = errors.New("websocket: read limit exceeded")
-
-// netError satisfies the net Error interface.
-type netError struct {
- msg string
- temporary bool
- timeout bool
-}
-
-func (e *netError) Error() string { return e.msg }
-func (e *netError) Temporary() bool { return e.temporary }
-func (e *netError) Timeout() bool { return e.timeout }
-
-// CloseError represents close frame.
-type CloseError struct {
-
- // Code is defined in RFC 6455, section 11.7.
- Code int
-
- // Text is the optional text payload.
- Text string
-}
-
-func (e *CloseError) Error() string {
- return "websocket: close " + strconv.Itoa(e.Code) + " " + e.Text
-}
-
-var (
- errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
- errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
- errBadWriteOpCode = errors.New("websocket: bad write message type")
- errWriteClosed = errors.New("websocket: write closed")
- errInvalidControlFrame = errors.New("websocket: invalid control frame")
-)
-
-func hideTempErr(err error) error {
- if e, ok := err.(net.Error); ok && e.Temporary() {
- err = &netError{msg: e.Error(), timeout: e.Timeout()}
- }
- return err
-}
-
-func isControl(frameType int) bool {
- return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
-}
-
-func isData(frameType int) bool {
- return frameType == TextMessage || frameType == BinaryMessage
-}
-
-func maskBytes(key [4]byte, pos int, b []byte) int {
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
- return pos & 3
-}
-
-func newMaskKey() [4]byte {
- n := rand.Uint32()
- return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
-}
-
-// Conn represents a WebSocket connection.
-type Conn struct {
- conn net.Conn
- isServer bool
- subprotocol string
-
- // Write fields
- mu chan bool // used as mutex to protect write to conn and closeSent
- closeSent bool // true if close message was sent
-
- // Message writer fields.
- writeErr error
- writeBuf []byte // frame is constructed in this buffer.
- writePos int // end of data in writeBuf.
- writeFrameType int // type of the current frame.
- writeSeq int // incremented to invalidate message writers.
- writeDeadline time.Time
-
- // Read fields
- readErr error
- br *bufio.Reader
- readRemaining int64 // bytes remaining in current frame.
- readFinal bool // true the current message has more frames.
- readSeq int // incremented to invalidate message readers.
- readLength int64 // Message size.
- readLimit int64 // Maximum message size.
- readMaskPos int
- readMaskKey [4]byte
- handlePong func(string) error
- handlePing func(string) error
-}
-
-func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
- mu := make(chan bool, 1)
- mu <- true
-
- if readBufferSize == 0 {
- readBufferSize = defaultReadBufferSize
- }
- if writeBufferSize == 0 {
- writeBufferSize = defaultWriteBufferSize
- }
-
- c := &Conn{
- isServer: isServer,
- br: bufio.NewReaderSize(conn, readBufferSize),
- conn: conn,
- mu: mu,
- readFinal: true,
- writeBuf: make([]byte, writeBufferSize+maxFrameHeaderSize),
- writeFrameType: noFrame,
- writePos: maxFrameHeaderSize,
- }
- c.SetPingHandler(nil)
- c.SetPongHandler(nil)
- return c
-}
-
-// Subprotocol returns the negotiated protocol for the connection.
-func (c *Conn) Subprotocol() string {
- return c.subprotocol
-}
-
-// Close closes the underlying network connection without sending or waiting for a close frame.
-func (c *Conn) Close() error {
- return c.conn.Close()
-}
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
- return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
- return c.conn.RemoteAddr()
-}
-
-// Write methods
-
-func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
- <-c.mu
- defer func() { c.mu <- true }()
-
- if c.closeSent {
- return ErrCloseSent
- } else if frameType == CloseMessage {
- c.closeSent = true
- }
-
- c.conn.SetWriteDeadline(deadline)
- for _, buf := range bufs {
- if len(buf) > 0 {
- n, err := c.conn.Write(buf)
- if n != len(buf) {
- // Close on partial write.
- c.conn.Close()
- }
- if err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-// WriteControl writes a control message with the given deadline. The allowed
-// message types are CloseMessage, PingMessage and PongMessage.
-func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
- if !isControl(messageType) {
- return errBadWriteOpCode
- }
- if len(data) > maxControlFramePayloadSize {
- return errInvalidControlFrame
- }
-
- b0 := byte(messageType) | finalBit
- b1 := byte(len(data))
- if !c.isServer {
- b1 |= maskBit
- }
-
- buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
- buf = append(buf, b0, b1)
-
- if c.isServer {
- buf = append(buf, data...)
- } else {
- key := newMaskKey()
- buf = append(buf, key[:]...)
- buf = append(buf, data...)
- maskBytes(key, 0, buf[6:])
- }
-
- d := time.Hour * 1000
- if !deadline.IsZero() {
- d = deadline.Sub(time.Now())
- if d < 0 {
- return errWriteTimeout
- }
- }
-
- timer := time.NewTimer(d)
- select {
- case <-c.mu:
- timer.Stop()
- case <-timer.C:
- return errWriteTimeout
- }
- defer func() { c.mu <- true }()
-
- if c.closeSent {
- return ErrCloseSent
- } else if messageType == CloseMessage {
- c.closeSent = true
- }
-
- c.conn.SetWriteDeadline(deadline)
- n, err := c.conn.Write(buf)
- if n != 0 && n != len(buf) {
- c.conn.Close()
- }
- return hideTempErr(err)
-}
-
-// NextWriter returns a writer for the next message to send. The writer's
-// Close method flushes the complete message to the network.
-//
-// There can be at most one open writer on a connection. NextWriter closes the
-// previous writer if the application has not already done so.
-//
-// The NextWriter method and the writers returned from the method cannot be
-// accessed by more than one goroutine at a time.
-func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
- if c.writeErr != nil {
- return nil, c.writeErr
- }
-
- if c.writeFrameType != noFrame {
- if err := c.flushFrame(true, nil); err != nil {
- return nil, err
- }
- }
-
- if !isControl(messageType) && !isData(messageType) {
- return nil, errBadWriteOpCode
- }
-
- c.writeFrameType = messageType
- return messageWriter{c, c.writeSeq}, nil
-}
-
-func (c *Conn) flushFrame(final bool, extra []byte) error {
- length := c.writePos - maxFrameHeaderSize + len(extra)
-
- // Check for invalid control frames.
- if isControl(c.writeFrameType) &&
- (!final || length > maxControlFramePayloadSize) {
- c.writeSeq++
- c.writeFrameType = noFrame
- c.writePos = maxFrameHeaderSize
- return errInvalidControlFrame
- }
-
- b0 := byte(c.writeFrameType)
- if final {
- b0 |= finalBit
- }
- b1 := byte(0)
- if !c.isServer {
- b1 |= maskBit
- }
-
- // Assume that the frame starts at beginning of c.writeBuf.
- framePos := 0
- if c.isServer {
- // Adjust up if mask not included in the header.
- framePos = 4
- }
-
- switch {
- case length >= 65536:
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | 127
- binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
- case length > 125:
- framePos += 6
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | 126
- binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
- default:
- framePos += 8
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | byte(length)
- }
-
- if !c.isServer {
- key := newMaskKey()
- copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
- maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:c.writePos])
- if len(extra) > 0 {
- c.writeErr = errors.New("websocket: internal error, extra used in client mode")
- return c.writeErr
- }
- }
-
- // Write the buffers to the connection.
- c.writeErr = c.write(c.writeFrameType, c.writeDeadline, c.writeBuf[framePos:c.writePos], extra)
-
- // Setup for next frame.
- c.writePos = maxFrameHeaderSize
- c.writeFrameType = continuationFrame
- if final {
- c.writeSeq++
- c.writeFrameType = noFrame
- }
- return c.writeErr
-}
-
-type messageWriter struct {
- c *Conn
- seq int
-}
-
-func (w messageWriter) err() error {
- c := w.c
- if c.writeSeq != w.seq {
- return errWriteClosed
- }
- if c.writeErr != nil {
- return c.writeErr
- }
- return nil
-}
-
-func (w messageWriter) ncopy(max int) (int, error) {
- n := len(w.c.writeBuf) - w.c.writePos
- if n <= 0 {
- if err := w.c.flushFrame(false, nil); err != nil {
- return 0, err
- }
- n = len(w.c.writeBuf) - w.c.writePos
- }
- if n > max {
- n = max
- }
- return n, nil
-}
-
-func (w messageWriter) write(final bool, p []byte) (int, error) {
- if err := w.err(); err != nil {
- return 0, err
- }
-
- if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
- // Don't buffer large messages.
- err := w.c.flushFrame(final, p)
- if err != nil {
- return 0, err
- }
- return len(p), nil
- }
-
- nn := len(p)
- for len(p) > 0 {
- n, err := w.ncopy(len(p))
- if err != nil {
- return 0, err
- }
- copy(w.c.writeBuf[w.c.writePos:], p[:n])
- w.c.writePos += n
- p = p[n:]
- }
- return nn, nil
-}
-
-func (w messageWriter) Write(p []byte) (int, error) {
- return w.write(false, p)
-}
-
-func (w messageWriter) WriteString(p string) (int, error) {
- if err := w.err(); err != nil {
- return 0, err
- }
-
- nn := len(p)
- for len(p) > 0 {
- n, err := w.ncopy(len(p))
- if err != nil {
- return 0, err
- }
- copy(w.c.writeBuf[w.c.writePos:], p[:n])
- w.c.writePos += n
- p = p[n:]
- }
- return nn, nil
-}
-
-func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
- if err := w.err(); err != nil {
- return 0, err
- }
- for {
- if w.c.writePos == len(w.c.writeBuf) {
- err = w.c.flushFrame(false, nil)
- if err != nil {
- break
- }
- }
- var n int
- n, err = r.Read(w.c.writeBuf[w.c.writePos:])
- w.c.writePos += n
- nn += int64(n)
- if err != nil {
- if err == io.EOF {
- err = nil
- }
- break
- }
- }
- return nn, err
-}
-
-func (w messageWriter) Close() error {
- if err := w.err(); err != nil {
- return err
- }
- return w.c.flushFrame(true, nil)
-}
-
-// WriteMessage is a helper method for getting a writer using NextWriter,
-// writing the message and closing the writer.
-func (c *Conn) WriteMessage(messageType int, data []byte) error {
- wr, err := c.NextWriter(messageType)
- if err != nil {
- return err
- }
- w := wr.(messageWriter)
- if _, err := w.write(true, data); err != nil {
- return err
- }
- if c.writeSeq == w.seq {
- if err := c.flushFrame(true, nil); err != nil {
- return err
- }
- }
- return nil
-}
-
-// SetWriteDeadline sets the write deadline on the underlying network
-// connection. After a write has timed out, the websocket state is corrupt and
-// all future writes will return an error. A zero value for t means writes will
-// not time out.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
- c.writeDeadline = t
- return nil
-}
-
-// Read methods
-
-// readFull is like io.ReadFull except that io.EOF is never returned.
-func (c *Conn) readFull(p []byte) (err error) {
- var n int
- for n < len(p) && err == nil {
- var nn int
- nn, err = c.br.Read(p[n:])
- n += nn
- }
- if n == len(p) {
- err = nil
- } else if err == io.EOF {
- err = errUnexpectedEOF
- }
- return
-}
-
-func (c *Conn) advanceFrame() (int, error) {
-
- // 1. Skip remainder of previous frame.
-
- if c.readRemaining > 0 {
- if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
- return noFrame, err
- }
- }
-
- // 2. Read and parse first two bytes of frame header.
-
- var b [8]byte
- if err := c.readFull(b[:2]); err != nil {
- return noFrame, err
- }
-
- final := b[0]&finalBit != 0
- frameType := int(b[0] & 0xf)
- reserved := int((b[0] >> 4) & 0x7)
- mask := b[1]&maskBit != 0
- c.readRemaining = int64(b[1] & 0x7f)
-
- if reserved != 0 {
- return noFrame, c.handleProtocolError("unexpected reserved bits " + strconv.Itoa(reserved))
- }
-
- switch frameType {
- case CloseMessage, PingMessage, PongMessage:
- if c.readRemaining > maxControlFramePayloadSize {
- return noFrame, c.handleProtocolError("control frame length > 125")
- }
- if !final {
- return noFrame, c.handleProtocolError("control frame not final")
- }
- case TextMessage, BinaryMessage:
- if !c.readFinal {
- return noFrame, c.handleProtocolError("message start before final message frame")
- }
- c.readFinal = final
- case continuationFrame:
- if c.readFinal {
- return noFrame, c.handleProtocolError("continuation after final message frame")
- }
- c.readFinal = final
- default:
- return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
- }
-
- // 3. Read and parse frame length.
-
- switch c.readRemaining {
- case 126:
- if err := c.readFull(b[:2]); err != nil {
- return noFrame, err
- }
- c.readRemaining = int64(binary.BigEndian.Uint16(b[:2]))
- case 127:
- if err := c.readFull(b[:8]); err != nil {
- return noFrame, err
- }
- c.readRemaining = int64(binary.BigEndian.Uint64(b[:8]))
- }
-
- // 4. Handle frame masking.
-
- if mask != c.isServer {
- return noFrame, c.handleProtocolError("incorrect mask flag")
- }
-
- if mask {
- c.readMaskPos = 0
- if err := c.readFull(c.readMaskKey[:]); err != nil {
- return noFrame, err
- }
- }
-
- // 5. For text and binary messages, enforce read limit and return.
-
- if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
-
- c.readLength += c.readRemaining
- if c.readLimit > 0 && c.readLength > c.readLimit {
- c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
- return noFrame, ErrReadLimit
- }
-
- return frameType, nil
- }
-
- // 6. Read control frame payload.
-
- var payload []byte
- if c.readRemaining > 0 {
- payload = make([]byte, c.readRemaining)
- c.readRemaining = 0
- if err := c.readFull(payload); err != nil {
- return noFrame, err
- }
- if c.isServer {
- maskBytes(c.readMaskKey, 0, payload)
- }
- }
-
- // 7. Process control frame payload.
-
- switch frameType {
- case PongMessage:
- if err := c.handlePong(string(payload)); err != nil {
- return noFrame, err
- }
- case PingMessage:
- if err := c.handlePing(string(payload)); err != nil {
- return noFrame, err
- }
- case CloseMessage:
- c.WriteControl(CloseMessage, []byte{}, time.Now().Add(writeWait))
- closeCode := CloseNoStatusReceived
- closeText := ""
- if len(payload) >= 2 {
- closeCode = int(binary.BigEndian.Uint16(payload))
- closeText = string(payload[2:])
- }
- return noFrame, &CloseError{Code: closeCode, Text: closeText}
- }
-
- return frameType, nil
-}
-
-func (c *Conn) handleProtocolError(message string) error {
- c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
- return errors.New("websocket: " + message)
-}
-
-// NextReader returns the next data message received from the peer. The
-// returned messageType is either TextMessage or BinaryMessage.
-//
-// There can be at most one open reader on a connection. NextReader discards
-// the previous message if the application has not already consumed it.
-//
-// The NextReader method and the readers returned from the method cannot be
-// accessed by more than one goroutine at a time.
-func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
-
- c.readSeq++
- c.readLength = 0
-
- for c.readErr == nil {
- frameType, err := c.advanceFrame()
- if err != nil {
- c.readErr = hideTempErr(err)
- break
- }
- if frameType == TextMessage || frameType == BinaryMessage {
- return frameType, messageReader{c, c.readSeq}, nil
- }
- }
- return noFrame, nil, c.readErr
-}
-
-type messageReader struct {
- c *Conn
- seq int
-}
-
-func (r messageReader) Read(b []byte) (int, error) {
-
- if r.seq != r.c.readSeq {
- return 0, io.EOF
- }
-
- for r.c.readErr == nil {
-
- if r.c.readRemaining > 0 {
- if int64(len(b)) > r.c.readRemaining {
- b = b[:r.c.readRemaining]
- }
- n, err := r.c.br.Read(b)
- r.c.readErr = hideTempErr(err)
- if r.c.isServer {
- r.c.readMaskPos = maskBytes(r.c.readMaskKey, r.c.readMaskPos, b[:n])
- }
- r.c.readRemaining -= int64(n)
- return n, r.c.readErr
- }
-
- if r.c.readFinal {
- r.c.readSeq++
- return 0, io.EOF
- }
-
- frameType, err := r.c.advanceFrame()
- switch {
- case err != nil:
- r.c.readErr = hideTempErr(err)
- case frameType == TextMessage || frameType == BinaryMessage:
- r.c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
- }
- }
-
- err := r.c.readErr
- if err == io.EOF && r.seq == r.c.readSeq {
- err = errUnexpectedEOF
- }
- return 0, err
-}
-
-// ReadMessage is a helper method for getting a reader using NextReader and
-// reading from that reader to a buffer.
-func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
- var r io.Reader
- messageType, r, err = c.NextReader()
- if err != nil {
- return messageType, nil, err
- }
- p, err = ioutil.ReadAll(r)
- return messageType, p, err
-}
-
-// SetReadDeadline sets the read deadline on the underlying network connection.
-// After a read has timed out, the websocket connection state is corrupt and
-// all future reads will return an error. A zero value for t means reads will
-// not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
- return c.conn.SetReadDeadline(t)
-}
-
-// SetReadLimit sets the maximum size for a message read from the peer. If a
-// message exceeds the limit, the connection sends a close frame to the peer
-// and returns ErrReadLimit to the application.
-func (c *Conn) SetReadLimit(limit int64) {
- c.readLimit = limit
-}
-
-// SetPingHandler sets the handler for ping messages received from the peer.
-// The appData argument to h is the PING frame application data. The default
-// ping handler sends a pong to the peer.
-func (c *Conn) SetPingHandler(h func(appData string) error) {
- if h == nil {
- h = func(message string) error {
- err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
- if err == ErrCloseSent {
- return nil
- } else if e, ok := err.(net.Error); ok && e.Temporary() {
- return nil
- }
- return err
- }
- }
- c.handlePing = h
-}
-
-// SetPongHandler sets the handler for pong messages received from the peer.
-// The appData argument to h is the PONG frame application data. The default
-// pong handler does nothing.
-func (c *Conn) SetPongHandler(h func(appData string) error) {
- if h == nil {
- h = func(string) error { return nil }
- }
- c.handlePong = h
-}
-
-// UnderlyingConn returns the internal net.Conn. This can be used to further
-// modifications to connection specific flags.
-func (c *Conn) UnderlyingConn() net.Conn {
- return c.conn
-}
-
-// FormatCloseMessage formats closeCode and text as a WebSocket close message.
-func FormatCloseMessage(closeCode int, text string) []byte {
- buf := make([]byte, 2+len(text))
- binary.BigEndian.PutUint16(buf, uint16(closeCode))
- copy(buf[2:], text)
- return buf
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go b/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
deleted file mode 100644
index 72286279c..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package websocket implements the WebSocket protocol defined in RFC 6455.
-//
-// Overview
-//
-// The Conn type represents a WebSocket connection. A server application uses
-// the Upgrade function from an Upgrader object with a HTTP request handler
-// to get a pointer to a Conn:
-//
-// var upgrader = websocket.Upgrader{
-// ReadBufferSize: 1024,
-// WriteBufferSize: 1024,
-// }
-//
-// func handler(w http.ResponseWriter, r *http.Request) {
-// conn, err := upgrader.Upgrade(w, r, nil)
-// if err != nil {
-// log.Println(err)
-// return
-// }
-// ... Use conn to send and receive messages.
-// }
-//
-// Call the connection's WriteMessage and ReadMessage methods to send and
-// receive messages as a slice of bytes. This snippet of code shows how to echo
-// messages using these methods:
-//
-// for {
-// messageType, p, err := conn.ReadMessage()
-// if err != nil {
-// return
-// }
-// if err = conn.WriteMessage(messageType, p); err != nil {
-// return err
-// }
-// }
-//
-// In above snippet of code, p is a []byte and messageType is an int with value
-// websocket.BinaryMessage or websocket.TextMessage.
-//
-// An application can also send and receive messages using the io.WriteCloser
-// and io.Reader interfaces. To send a message, call the connection NextWriter
-// method to get an io.WriteCloser, write the message to the writer and close
-// the writer when done. To receive a message, call the connection NextReader
-// method to get an io.Reader and read until io.EOF is returned. This snippet
-// snippet shows how to echo messages using the NextWriter and NextReader
-// methods:
-//
-// for {
-// messageType, r, err := conn.NextReader()
-// if err != nil {
-// return
-// }
-// w, err := conn.NextWriter(messageType)
-// if err != nil {
-// return err
-// }
-// if _, err := io.Copy(w, r); err != nil {
-// return err
-// }
-// if err := w.Close(); err != nil {
-// return err
-// }
-// }
-//
-// Data Messages
-//
-// The WebSocket protocol distinguishes between text and binary data messages.
-// Text messages are interpreted as UTF-8 encoded text. The interpretation of
-// binary messages is left to the application.
-//
-// This package uses the TextMessage and BinaryMessage integer constants to
-// identify the two data message types. The ReadMessage and NextReader methods
-// return the type of the received message. The messageType argument to the
-// WriteMessage and NextWriter methods specifies the type of a sent message.
-//
-// It is the application's responsibility to ensure that text messages are
-// valid UTF-8 encoded text.
-//
-// Control Messages
-//
-// The WebSocket protocol defines three types of control messages: close, ping
-// and pong. Call the connection WriteControl, WriteMessage or NextWriter
-// methods to send a control message to the peer.
-//
-// Connections handle received ping and pong messages by invoking a callback
-// function set with SetPingHandler and SetPongHandler methods. These callback
-// functions can be invoked from the ReadMessage method, the NextReader method
-// or from a call to the data message reader returned from NextReader.
-//
-// Connections handle received close messages by returning an error from the
-// ReadMessage method, the NextReader method or from a call to the data message
-// reader returned from NextReader.
-//
-// Concurrency
-//
-// Connections support one concurrent reader and one concurrent writer.
-//
-// Applications are responsible for ensuring that no more than one goroutine
-// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
-// WriteJSON) concurrently and that no more than one goroutine calls the read
-// methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler,
-// SetPingHandler) concurrently.
-//
-// The Close and WriteControl methods can be called concurrently with all other
-// methods.
-//
-// Read is Required
-//
-// The application must read the connection to process ping and close messages
-// sent from the peer. If the application is not otherwise interested in
-// messages from the peer, then the application should start a goroutine to read
-// and discard messages from the peer. A simple example is:
-//
-// func readLoop(c *websocket.Conn) {
-// for {
-// if _, _, err := c.NextReader(); err != nil {
-// c.Close()
-// break
-// }
-// }
-// }
-//
-// Origin Considerations
-//
-// Web browsers allow Javascript applications to open a WebSocket connection to
-// any host. It's up to the server to enforce an origin policy using the Origin
-// request header sent by the browser.
-//
-// The Upgrader calls the function specified in the CheckOrigin field to check
-// the origin. If the CheckOrigin function returns false, then the Upgrade
-// method fails the WebSocket handshake with HTTP status 403.
-//
-// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
-// the handshake if the Origin request header is present and not equal to the
-// Host request header.
-//
-// An application can allow connections from any origin by specifying a
-// function that always returns true:
-//
-// var upgrader = websocket.Upgrader{
-// CheckOrigin: func(r *http.Request) bool { return true },
-// }
-//
-// The deprecated Upgrade function does not enforce an origin policy. It's the
-// application's responsibility to check the Origin header before calling
-// Upgrade.
-package websocket
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md
deleted file mode 100644
index 075ac1530..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Test Server
-
-This package contains a server for the [Autobahn WebSockets Test Suite](http://autobahn.ws/testsuite).
-
-To test the server, run
-
- go run server.go
-
-and start the client test driver
-
- wstest -m fuzzingclient -s fuzzingclient.json
-
-When the client completes, it writes a report to reports/clients/index.html.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
deleted file mode 100644
index 27d5a5b14..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
+++ /dev/null
@@ -1,14 +0,0 @@
-
-{
- "options": {"failByDrop": false},
- "outdir": "./reports/clients",
- "servers": [
- {"agent": "ReadAllWriteMessage", "url": "ws://localhost:9000/m", "options": {"version": 18}},
- {"agent": "ReadAllWrite", "url": "ws://localhost:9000/r", "options": {"version": 18}},
- {"agent": "CopyFull", "url": "ws://localhost:9000/f", "options": {"version": 18}},
- {"agent": "CopyWriterOnly", "url": "ws://localhost:9000/c", "options": {"version": 18}}
- ],
- "cases": ["*"],
- "exclude-cases": [],
- "exclude-agent-cases": {}
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
deleted file mode 100644
index d96ac84db..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Command server is a test server for the Autobahn WebSockets Test Suite.
-package main
-
-import (
- "errors"
- "flag"
- "github.com/gorilla/websocket"
- "io"
- "log"
- "net/http"
- "time"
- "unicode/utf8"
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 4096,
- WriteBufferSize: 4096,
- CheckOrigin: func(r *http.Request) bool {
- return true
- },
-}
-
-// echoCopy echoes messages from the client using io.Copy.
-func echoCopy(w http.ResponseWriter, r *http.Request, writerOnly bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, r, err := conn.NextReader()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- if writerOnly {
- _, err = io.Copy(struct{ io.Writer }{w}, r)
- } else {
- _, err = io.Copy(w, r)
- }
- if err != nil {
- if err == errInvalidUTF8 {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- }
- log.Println("Copy:", err)
- return
- }
- err = w.Close()
- if err != nil {
- log.Println("Close:", err)
- return
- }
- }
-}
-
-func echoCopyWriterOnly(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, true)
-}
-
-func echoCopyFull(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, false)
-}
-
-// echoReadAll echoes messages from the client by reading the entire message
-// with ioutil.ReadAll.
-func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, b, err := conn.ReadMessage()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- if !utf8.Valid(b) {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- log.Println("ReadAll: invalid utf8")
- }
- }
- if writeMessage {
- err = conn.WriteMessage(mt, b)
- if err != nil {
- log.Println("WriteMessage:", err)
- }
- } else {
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if _, err := w.Write(b); err != nil {
- log.Println("Writer:", err)
- return
- }
- if err := w.Close(); err != nil {
- log.Println("Close:", err)
- return
- }
- }
- }
-}
-
-func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, false)
-}
-
-func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, true)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found.", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- io.WriteString(w, "<html><body>Echo Server</body></html>")
-}
-
-var addr = flag.String("addr", ":9000", "http service address")
-
-func main() {
- flag.Parse()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/c", echoCopyWriterOnly)
- http.HandleFunc("/f", echoCopyFull)
- http.HandleFunc("/r", echoReadAllWriter)
- http.HandleFunc("/m", echoReadAllWriteMessage)
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
-
-type validator struct {
- state int
- x rune
- r io.Reader
-}
-
-var errInvalidUTF8 = errors.New("invalid utf8")
-
-func (r *validator) Read(p []byte) (int, error) {
- n, err := r.r.Read(p)
- state := r.state
- x := r.x
- for _, b := range p[:n] {
- state, x = decode(state, x, b)
- if state == utf8Reject {
- break
- }
- }
- r.state = state
- r.x = x
- if state == utf8Reject || (err == io.EOF && state != utf8Accept) {
- return n, errInvalidUTF8
- }
- return n, err
-}
-
-// UTF-8 decoder from http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
-//
-// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-//
-// 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.
-var utf8d = [...]byte{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf
- 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df
- 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef
- 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // f0..ff
- 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
- 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
- 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8
-}
-
-const (
- utf8Accept = 0
- utf8Reject = 1
-)
-
-func decode(state int, x rune, b byte) (int, rune) {
- t := utf8d[b]
- if state != utf8Accept {
- x = rune(b&0x3f) | (x << 6)
- } else {
- x = rune((0xff >> t) & b)
- }
- state = int(utf8d[256+state*16+int(t)])
- return state, x
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
deleted file mode 100644
index 5df3cf1a3..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Chat Example
-
-This application shows how to use use the
-[websocket](https://github.com/gorilla/websocket) package and
-[jQuery](http://jquery.com) to implement a simple web chat application.
-
-## Running the example
-
-The example requires a working Go development environment. The [Getting
-Started](http://golang.org/doc/install) page describes how to install the
-development environment.
-
-Once you have Go up and running, you can download, build and run the example
-using the following commands.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
- $ go run *.go
-
-To use the chat example, open http://localhost:8080/ in your browser.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
deleted file mode 100644
index 22816f09f..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "github.com/gorilla/websocket"
- "log"
- "net/http"
- "time"
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Maximum message size allowed from peer.
- maxMessageSize = 512
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
-}
-
-// connection is an middleman between the websocket connection and the hub.
-type connection struct {
- // The websocket connection.
- ws *websocket.Conn
-
- // Buffered channel of outbound messages.
- send chan []byte
-}
-
-// readPump pumps messages from the websocket connection to the hub.
-func (c *connection) readPump() {
- defer func() {
- h.unregister <- c
- c.ws.Close()
- }()
- c.ws.SetReadLimit(maxMessageSize)
- c.ws.SetReadDeadline(time.Now().Add(pongWait))
- c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := c.ws.ReadMessage()
- if err != nil {
- break
- }
- h.broadcast <- message
- }
-}
-
-// write writes a message with the given message type and payload.
-func (c *connection) write(mt int, payload []byte) error {
- c.ws.SetWriteDeadline(time.Now().Add(writeWait))
- return c.ws.WriteMessage(mt, payload)
-}
-
-// writePump pumps messages from the hub to the websocket connection.
-func (c *connection) writePump() {
- ticker := time.NewTicker(pingPeriod)
- defer func() {
- ticker.Stop()
- c.ws.Close()
- }()
- for {
- select {
- case message, ok := <-c.send:
- if !ok {
- c.write(websocket.CloseMessage, []byte{})
- return
- }
- if err := c.write(websocket.TextMessage, message); err != nil {
- return
- }
- case <-ticker.C:
- if err := c.write(websocket.PingMessage, []byte{}); err != nil {
- return
- }
- }
- }
-}
-
-// serveWs handles websocket requests from the peer.
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println(err)
- return
- }
- c := &connection{send: make(chan []byte, 256), ws: ws}
- h.register <- c
- go c.writePump()
- c.readPump()
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html
deleted file mode 100644
index 29599225c..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Chat Example</title>
-<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
-<script type="text/javascript">
- $(function() {
-
- var conn;
- var msg = $("#msg");
- var log = $("#log");
-
- function appendLog(msg) {
- var d = log[0]
- var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
- msg.appendTo(log)
- if (doScroll) {
- d.scrollTop = d.scrollHeight - d.clientHeight;
- }
- }
-
- $("#form").submit(function() {
- if (!conn) {
- return false;
- }
- if (!msg.val()) {
- return false;
- }
- conn.send(msg.val());
- msg.val("");
- return false
- });
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://{{$}}/ws");
- conn.onclose = function(evt) {
- appendLog($("<div><b>Connection closed.</b></div>"))
- }
- conn.onmessage = function(evt) {
- appendLog($("<div/>").text(evt.data))
- }
- } else {
- appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
- }
- });
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go
deleted file mode 100644
index 449ba753d..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-// hub maintains the set of active connections and broadcasts messages to the
-// connections.
-type hub struct {
- // Registered connections.
- connections map[*connection]bool
-
- // Inbound messages from the connections.
- broadcast chan []byte
-
- // Register requests from the connections.
- register chan *connection
-
- // Unregister requests from connections.
- unregister chan *connection
-}
-
-var h = hub{
- broadcast: make(chan []byte),
- register: make(chan *connection),
- unregister: make(chan *connection),
- connections: make(map[*connection]bool),
-}
-
-func (h *hub) run() {
- for {
- select {
- case c := <-h.register:
- h.connections[c] = true
- case c := <-h.unregister:
- if _, ok := h.connections[c]; ok {
- delete(h.connections, c)
- close(c.send)
- }
- case m := <-h.broadcast:
- for c := range h.connections {
- select {
- case c.send <- m:
- default:
- close(c.send)
- delete(h.connections, c)
- }
- }
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go
deleted file mode 100644
index 3c4448d72..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "log"
- "net/http"
- "text/template"
-)
-
-var addr = flag.String("addr", ":8080", "http service address")
-var homeTempl = template.Must(template.ParseFiles("home.html"))
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- homeTempl.Execute(w, r.Host)
-}
-
-func main() {
- flag.Parse()
- go h.run()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md
deleted file mode 100644
index c30d3979a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Command example
-
-This example connects a websocket connection to stdin and stdout of a command.
-Received messages are written to stdin followed by a `\n`. Each line read from
-from standard out is sent as a message to the client.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/command`
- $ go run main.go <command and arguments to run>
- # Open http://localhost:8080/ .
-
-Try the following commands.
-
- # Echo sent messages to the output area.
- $ go run main.go cat
-
- # Run a shell.Try sending "ls" and "cat main.go".
- $ go run main.go sh
-
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html
deleted file mode 100644
index 72fd02b2a..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Command Example</title>
-<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
-<script type="text/javascript">
- $(function() {
-
- var conn;
- var msg = $("#msg");
- var log = $("#log");
-
- function appendLog(msg) {
- var d = log[0]
- var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
- msg.appendTo(log)
- if (doScroll) {
- d.scrollTop = d.scrollHeight - d.clientHeight;
- }
- }
-
- $("#form").submit(function() {
- if (!conn) {
- return false;
- }
- if (!msg.val()) {
- return false;
- }
- conn.send(msg.val());
- msg.val("");
- return false
- });
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://{{$}}/ws");
- conn.onclose = function(evt) {
- appendLog($("<div><b>Connection closed.</b></div>"))
- }
- conn.onmessage = function(evt) {
- appendLog($("<pre/>").text(evt.data))
- }
- } else {
- appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
- }
- });
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#log pre {
- margin: 0;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go
deleted file mode 100644
index f3f022edb..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bufio"
- "flag"
- "io"
- "log"
- "net/http"
- "os"
- "os/exec"
- "text/template"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- addr = flag.String("addr", "127.0.0.1:8080", "http service address")
- cmdPath string
- homeTempl = template.Must(template.ParseFiles("home.html"))
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Maximum message size allowed from peer.
- maxMessageSize = 8192
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-)
-
-func pumpStdin(ws *websocket.Conn, w io.Writer) {
- defer ws.Close()
- ws.SetReadLimit(maxMessageSize)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := ws.ReadMessage()
- if err != nil {
- break
- }
- message = append(message, '\n')
- if _, err := w.Write(message); err != nil {
- break
- }
- }
-}
-
-func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
- defer func() {
- ws.Close()
- close(done)
- }()
- s := bufio.NewScanner(r)
- for s.Scan() {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
- break
- }
- }
- if s.Err() != nil {
- log.Println("scan:", s.Err())
- }
-}
-
-func ping(ws *websocket.Conn, done chan struct{}) {
- ticker := time.NewTicker(pingPeriod)
- defer ticker.Stop()
- for {
- select {
- case <-ticker.C:
- if err := ws.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil {
- log.Println("ping:", err)
- }
- case <-done:
- return
- }
- }
-}
-
-func internalError(ws *websocket.Conn, msg string, err error) {
- log.Println(msg, err)
- ws.WriteMessage(websocket.TextMessage, []byte("Internal server error."))
-}
-
-var upgrader = websocket.Upgrader{}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("upgrade:", err)
- return
- }
-
- defer ws.Close()
-
- outr, outw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdout:", err)
- return
- }
- defer outr.Close()
- defer outw.Close()
-
- inr, inw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdin:", err)
- return
- }
- defer inr.Close()
- defer inw.Close()
-
- proc, err := os.StartProcess(cmdPath, flag.Args(), &os.ProcAttr{
- Files: []*os.File{inr, outw, outw},
- })
- if err != nil {
- internalError(ws, "start:", err)
- return
- }
-
- inr.Close()
- outw.Close()
-
- stdoutDone := make(chan struct{})
- go pumpStdout(ws, outr, stdoutDone)
- go ping(ws, stdoutDone)
-
- pumpStdin(ws, inw)
-
- // Some commands will exit when stdin is closed.
- inw.Close()
-
- // Other commands need a bonk on the head.
- if err := proc.Signal(os.Interrupt); err != nil {
- log.Println("inter:", err)
- }
-
- select {
- case <-stdoutDone:
- case <-time.After(time.Second):
- // A bigger bonk on the head.
- if err := proc.Signal(os.Kill); err != nil {
- log.Println("term:", err)
- }
- <-stdoutDone
- }
-
- if _, err := proc.Wait(); err != nil {
- log.Println("wait:", err)
- }
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- homeTempl.Execute(w, r.Host)
-}
-
-func main() {
- flag.Parse()
- if len(flag.Args()) < 1 {
- log.Fatal("must specify at least one argument")
- }
- var err error
- cmdPath, err = exec.LookPath(flag.Args()[0])
- if err != nil {
- log.Fatal(err)
- }
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md
deleted file mode 100644
index 6ad79ed76..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Client and server example
-
-This example shows a simple client and server.
-
-The server echoes messages sent to it. The client sends a message every second
-and prints all messages received.
-
-To run the example, start the server:
-
- $ go run server.go
-
-Next, start the client:
-
- $ go run client.go
-
-The server includes a simple web client. To use the client, open
-http://127.0.0.1:8080 in the browser and follow the instructions on the page.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go
deleted file mode 100644
index 6578094e7..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "log"
- "net/url"
- "os"
- "os/signal"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
-
- interrupt := make(chan os.Signal, 1)
- signal.Notify(interrupt, os.Interrupt)
-
- u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
- log.Printf("connecting to %s", u.String())
-
- c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
- if err != nil {
- log.Fatal("dial:", err)
- }
- defer c.Close()
-
- done := make(chan struct{})
-
- go func() {
- defer c.Close()
- defer close(done)
- for {
- _, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- return
- }
- log.Printf("recv: %s", message)
- }
- }()
-
- ticker := time.NewTicker(time.Second)
- defer ticker.Stop()
-
- for {
- select {
- case t := <-ticker.C:
- err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
- if err != nil {
- log.Println("write:", err)
- return
- }
- case <-interrupt:
- log.Println("interrupt")
- // To cleanly close a connection, a client should send a close
- // frame and wait for the server to close the connection.
- err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
- if err != nil {
- log.Println("write close:", err)
- return
- }
- select {
- case <-done:
- case <-time.After(time.Second):
- }
- c.Close()
- return
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go
deleted file mode 100644
index a685b0974..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "html/template"
- "log"
- "net/http"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-var upgrader = websocket.Upgrader{} // use default options
-
-func echo(w http.ResponseWriter, r *http.Request) {
- c, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Print("upgrade:", err)
- return
- }
- defer c.Close()
- for {
- mt, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- break
- }
- log.Printf("recv: %s", message)
- err = c.WriteMessage(mt, message)
- if err != nil {
- log.Println("write:", err)
- break
- }
- }
-}
-
-func home(w http.ResponseWriter, r *http.Request) {
- homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
-}
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
- http.HandleFunc("/echo", echo)
- http.HandleFunc("/", home)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
-
-var homeTemplate = template.Must(template.New("").Parse(`
-<!DOCTYPE html>
-<head>
-<meta charset="utf-8">
-<script>
-window.addEventListener("load", function(evt) {
-
- var output = document.getElementById("output");
- var input = document.getElementById("input");
- var ws;
-
- var print = function(message) {
- var d = document.createElement("div");
- d.innerHTML = message;
- output.appendChild(d);
- };
-
- document.getElementById("open").onclick = function(evt) {
- if (ws) {
- return false;
- }
- ws = new WebSocket("{{.}}");
- ws.onopen = function(evt) {
- print("OPEN");
- }
- ws.onclose = function(evt) {
- print("CLOSE");
- ws = null;
- }
- ws.onmessage = function(evt) {
- print("RESPONSE: " + evt.data);
- }
- ws.onerror = function(evt) {
- print("ERROR: " + evt.data);
- }
- return false;
- };
-
- document.getElementById("send").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- print("SEND: " + input.value);
- ws.send(input.value);
- return false;
- };
-
- document.getElementById("close").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- ws.close();
- return false;
- };
-
-});
-</script>
-</head>
-<body>
-<table>
-<tr><td valign="top" width="50%">
-<p>Click "Open" to create a connection to the server,
-"Send" to send a message to the server and "Close" to close the connection.
-You can change the message and send multiple times.
-<p>
-<form>
-<button id="open">Open</button>
-<button id="close">Close</button>
-<p><input id="input" type="text" value="Hello world!">
-<button id="send">Send</button>
-</form>
-</td><td valign="top" width="50%">
-<div id="output"></div>
-</td></tr></table>
-</body>
-</html>
-`))
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md
deleted file mode 100644
index ca4931f3b..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# File Watch example.
-
-This example sends a file to the browser client for display whenever the file is modified.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/filewatch`
- $ go run main.go <name of file to watch>
- # Open http://localhost:8080/ .
- # Modify the file to see it update in the browser.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
deleted file mode 100644
index a2c7b85fa..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strconv"
- "text/template"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-const (
- // Time allowed to write the file to the client.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the client.
- pongWait = 60 * time.Second
-
- // Send pings to client with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Poll file for changes with this period.
- filePeriod = 10 * time.Second
-)
-
-var (
- addr = flag.String("addr", ":8080", "http service address")
- homeTempl = template.Must(template.New("").Parse(homeHTML))
- filename string
- upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- }
-)
-
-func readFileIfModified(lastMod time.Time) ([]byte, time.Time, error) {
- fi, err := os.Stat(filename)
- if err != nil {
- return nil, lastMod, err
- }
- if !fi.ModTime().After(lastMod) {
- return nil, lastMod, nil
- }
- p, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, fi.ModTime(), err
- }
- return p, fi.ModTime(), nil
-}
-
-func reader(ws *websocket.Conn) {
- defer ws.Close()
- ws.SetReadLimit(512)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, _, err := ws.ReadMessage()
- if err != nil {
- break
- }
- }
-}
-
-func writer(ws *websocket.Conn, lastMod time.Time) {
- lastError := ""
- pingTicker := time.NewTicker(pingPeriod)
- fileTicker := time.NewTicker(filePeriod)
- defer func() {
- pingTicker.Stop()
- fileTicker.Stop()
- ws.Close()
- }()
- for {
- select {
- case <-fileTicker.C:
- var p []byte
- var err error
-
- p, lastMod, err = readFileIfModified(lastMod)
-
- if err != nil {
- if s := err.Error(); s != lastError {
- lastError = s
- p = []byte(lastError)
- }
- } else {
- lastError = ""
- }
-
- if p != nil {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, p); err != nil {
- return
- }
- }
- case <-pingTicker.C:
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
- return
- }
- }
- }
-}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- if _, ok := err.(websocket.HandshakeError); !ok {
- log.Println(err)
- }
- return
- }
-
- var lastMod time.Time
- if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err != nil {
- lastMod = time.Unix(0, n)
- }
-
- go writer(ws, lastMod)
- reader(ws)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- p, lastMod, err := readFileIfModified(time.Time{})
- if err != nil {
- p = []byte(err.Error())
- lastMod = time.Unix(0, 0)
- }
- var v = struct {
- Host string
- Data string
- LastMod string
- }{
- r.Host,
- string(p),
- strconv.FormatInt(lastMod.UnixNano(), 16),
- }
- homeTempl.Execute(w, &v)
-}
-
-func main() {
- flag.Parse()
- if flag.NArg() != 1 {
- log.Fatal("filename not specified")
- }
- filename = flag.Args()[0]
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- if err := http.ListenAndServe(*addr, nil); err != nil {
- log.Fatal(err)
- }
-}
-
-const homeHTML = `<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>WebSocket Example</title>
- </head>
- <body>
- <pre id="fileData">{{.Data}}</pre>
- <script type="text/javascript">
- (function() {
- var data = document.getElementById("fileData");
- var conn = new WebSocket("ws://{{.Host}}/ws?lastMod={{.LastMod}}");
- conn.onclose = function(evt) {
- data.textContent = 'Connection closed';
- }
- conn.onmessage = function(evt) {
- console.log('file updated');
- data.textContent = evt.data;
- }
- })();
- </script>
- </body>
-</html>
-`
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/json.go b/Godeps/_workspace/src/github.com/gorilla/websocket/json.go
deleted file mode 100644
index 4f0e36875..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/json.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "encoding/json"
- "io"
-)
-
-// WriteJSON is deprecated, use c.WriteJSON instead.
-func WriteJSON(c *Conn, v interface{}) error {
- return c.WriteJSON(v)
-}
-
-// WriteJSON writes the JSON encoding of v to the connection.
-//
-// See the documentation for encoding/json Marshal for details about the
-// conversion of Go values to JSON.
-func (c *Conn) WriteJSON(v interface{}) error {
- w, err := c.NextWriter(TextMessage)
- if err != nil {
- return err
- }
- err1 := json.NewEncoder(w).Encode(v)
- err2 := w.Close()
- if err1 != nil {
- return err1
- }
- return err2
-}
-
-// ReadJSON is deprecated, use c.ReadJSON instead.
-func ReadJSON(c *Conn, v interface{}) error {
- return c.ReadJSON(v)
-}
-
-// ReadJSON reads the next JSON-encoded message from the connection and stores
-// it in the value pointed to by v.
-//
-// See the documentation for the encoding/json Unmarshal function for details
-// about the conversion of JSON to a Go value.
-func (c *Conn) ReadJSON(v interface{}) error {
- _, r, err := c.NextReader()
- if err != nil {
- return err
- }
- err = json.NewDecoder(r).Decode(v)
- if err == io.EOF {
- // One value is expected in the message.
- err = io.ErrUnexpectedEOF
- }
- return err
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/server.go
deleted file mode 100644
index 3a9805f02..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/server.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bufio"
- "errors"
- "net"
- "net/http"
- "net/url"
- "strings"
- "time"
-)
-
-// HandshakeError describes an error with the handshake from the peer.
-type HandshakeError struct {
- message string
-}
-
-func (e HandshakeError) Error() string { return e.message }
-
-// Upgrader specifies parameters for upgrading an HTTP connection to a
-// WebSocket connection.
-type Upgrader struct {
- // HandshakeTimeout specifies the duration for the handshake to complete.
- HandshakeTimeout time.Duration
-
- // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
- // size is zero, then a default value of 4096 is used. The I/O buffer sizes
- // do not limit the size of the messages that can be sent or received.
- ReadBufferSize, WriteBufferSize int
-
- // Subprotocols specifies the server's supported protocols in order of
- // preference. If this field is set, then the Upgrade method negotiates a
- // subprotocol by selecting the first match in this list with a protocol
- // requested by the client.
- Subprotocols []string
-
- // Error specifies the function for generating HTTP error responses. If Error
- // is nil, then http.Error is used to generate the HTTP response.
- Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
-
- // CheckOrigin returns true if the request Origin header is acceptable. If
- // CheckOrigin is nil, the host in the Origin header must not be set or
- // must match the host of the request.
- CheckOrigin func(r *http.Request) bool
-}
-
-func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
- err := HandshakeError{reason}
- if u.Error != nil {
- u.Error(w, r, status, err)
- } else {
- http.Error(w, http.StatusText(status), status)
- }
- return nil, err
-}
-
-// checkSameOrigin returns true if the origin is not set or is equal to the request host.
-func checkSameOrigin(r *http.Request) bool {
- origin := r.Header["Origin"]
- if len(origin) == 0 {
- return true
- }
- u, err := url.Parse(origin[0])
- if err != nil {
- return false
- }
- return u.Host == r.Host
-}
-
-func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
- if u.Subprotocols != nil {
- clientProtocols := Subprotocols(r)
- for _, serverProtocol := range u.Subprotocols {
- for _, clientProtocol := range clientProtocols {
- if clientProtocol == serverProtocol {
- return clientProtocol
- }
- }
- }
- } else if responseHeader != nil {
- return responseHeader.Get("Sec-Websocket-Protocol")
- }
- return ""
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// application negotiated subprotocol (Sec-Websocket-Protocol).
-func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
- if r.Method != "GET" {
- return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: method not GET")
- }
- if values := r.Header["Sec-Websocket-Version"]; len(values) == 0 || values[0] != "13" {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13")
- }
-
- if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find connection header with token 'upgrade'")
- }
-
- if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find upgrade header with token 'websocket'")
- }
-
- checkOrigin := u.CheckOrigin
- if checkOrigin == nil {
- checkOrigin = checkSameOrigin
- }
- if !checkOrigin(r) {
- return u.returnError(w, r, http.StatusForbidden, "websocket: origin not allowed")
- }
-
- challengeKey := r.Header.Get("Sec-Websocket-Key")
- if challengeKey == "" {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: key missing or blank")
- }
-
- subprotocol := u.selectSubprotocol(r, responseHeader)
-
- var (
- netConn net.Conn
- br *bufio.Reader
- err error
- )
-
- h, ok := w.(http.Hijacker)
- if !ok {
- return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
- }
- var rw *bufio.ReadWriter
- netConn, rw, err = h.Hijack()
- if err != nil {
- return u.returnError(w, r, http.StatusInternalServerError, err.Error())
- }
- br = rw.Reader
-
- if br.Buffered() > 0 {
- netConn.Close()
- return nil, errors.New("websocket: client sent data before handshake is complete")
- }
-
- c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize)
- c.subprotocol = subprotocol
-
- p := c.writeBuf[:0]
- p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
- p = append(p, computeAcceptKey(challengeKey)...)
- p = append(p, "\r\n"...)
- if c.subprotocol != "" {
- p = append(p, "Sec-Websocket-Protocol: "...)
- p = append(p, c.subprotocol...)
- p = append(p, "\r\n"...)
- }
- for k, vs := range responseHeader {
- if k == "Sec-Websocket-Protocol" {
- continue
- }
- for _, v := range vs {
- p = append(p, k...)
- p = append(p, ": "...)
- for i := 0; i < len(v); i++ {
- b := v[i]
- if b <= 31 {
- // prevent response splitting.
- b = ' '
- }
- p = append(p, b)
- }
- p = append(p, "\r\n"...)
- }
- }
- p = append(p, "\r\n"...)
-
- // Clear deadlines set by HTTP server.
- netConn.SetDeadline(time.Time{})
-
- if u.HandshakeTimeout > 0 {
- netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
- }
- if _, err = netConn.Write(p); err != nil {
- netConn.Close()
- return nil, err
- }
- if u.HandshakeTimeout > 0 {
- netConn.SetWriteDeadline(time.Time{})
- }
-
- return c, nil
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// This function is deprecated, use websocket.Upgrader instead.
-//
-// The application is responsible for checking the request origin before
-// calling Upgrade. An example implementation of the same origin policy is:
-//
-// if req.Header.Get("Origin") != "http://"+req.Host {
-// http.Error(w, "Origin not allowed", 403)
-// return
-// }
-//
-// If the endpoint supports subprotocols, then the application is responsible
-// for negotiating the protocol used on the connection. Use the Subprotocols()
-// function to get the subprotocols requested by the client. Use the
-// Sec-Websocket-Protocol response header to specify the subprotocol selected
-// by the application.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// negotiated subprotocol (Sec-Websocket-Protocol).
-//
-// The connection buffers IO to the underlying network connection. The
-// readBufSize and writeBufSize parameters specify the size of the buffers to
-// use. Messages can be larger than the buffers.
-//
-// If the request is not a valid WebSocket handshake, then Upgrade returns an
-// error of type HandshakeError. Applications should handle this error by
-// replying to the client with an HTTP error response.
-func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
- u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
- u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
- // don't return errors to maintain backwards compatibility
- }
- u.CheckOrigin = func(r *http.Request) bool {
- // allow all connections by default
- return true
- }
- return u.Upgrade(w, r, responseHeader)
-}
-
-// Subprotocols returns the subprotocols requested by the client in the
-// Sec-Websocket-Protocol header.
-func Subprotocols(r *http.Request) []string {
- h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
- if h == "" {
- return nil
- }
- protocols := strings.Split(h, ",")
- for i := range protocols {
- protocols[i] = strings.TrimSpace(protocols[i])
- }
- return protocols
-}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/util.go b/Godeps/_workspace/src/github.com/gorilla/websocket/util.go
deleted file mode 100644
index ffdc265ed..000000000
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/util.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "crypto/rand"
- "crypto/sha1"
- "encoding/base64"
- "io"
- "net/http"
- "strings"
-)
-
-// tokenListContainsValue returns true if the 1#token header with the given
-// name contains token.
-func tokenListContainsValue(header http.Header, name string, value string) bool {
- for _, v := range header[name] {
- for _, s := range strings.Split(v, ",") {
- if strings.EqualFold(value, strings.TrimSpace(s)) {
- return true
- }
- }
- }
- return false
-}
-
-var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
-
-func computeAcceptKey(challengeKey string) string {
- h := sha1.New()
- h.Write([]byte(challengeKey))
- h.Write(keyGUID)
- return base64.StdEncoding.EncodeToString(h.Sum(nil))
-}
-
-func generateChallengeKey() (string, error) {
- p := make([]byte, 16)
- if _, err := io.ReadFull(rand.Reader, p); err != nil {
- return "", err
- }
- return base64.StdEncoding.EncodeToString(p), nil
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/.gitignore b/Godeps/_workspace/src/github.com/lib/pq/.gitignore
deleted file mode 100644
index 0f1d00e11..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.db
-*.test
-*~
-*.swp
diff --git a/Godeps/_workspace/src/github.com/lib/pq/.travis.yml b/Godeps/_workspace/src/github.com/lib/pq/.travis.yml
deleted file mode 100644
index 6b8eb405b..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/.travis.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-language: go
-
-go:
- - 1.1
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - tip
-
-before_install:
- - psql --version
- - sudo /etc/init.d/postgresql stop
- - sudo apt-get -y --purge remove postgresql libpq-dev libpq5 postgresql-client-common postgresql-common
- - sudo rm -rf /var/lib/postgresql
- - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
- - sudo sh -c "echo deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main $PGVERSION >> /etc/apt/sources.list.d/postgresql.list"
- - sudo apt-get update -qq
- - sudo apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::="--force-confnew" install postgresql-$PGVERSION postgresql-server-dev-$PGVERSION postgresql-contrib-$PGVERSION
- - sudo chmod 777 /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "local all postgres trust" > /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "local all all trust" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostnossl all pqgossltest 127.0.0.1/32 reject" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostnossl all pqgosslcert 127.0.0.1/32 reject" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostssl all pqgossltest 127.0.0.1/32 trust" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostssl all pqgosslcert 127.0.0.1/32 cert" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "host all all 127.0.0.1/32 trust" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostnossl all pqgossltest ::1/128 reject" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostnossl all pqgosslcert ::1/128 reject" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostssl all pqgossltest ::1/128 trust" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "hostssl all pqgosslcert ::1/128 cert" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - echo "host all all ::1/128 trust" >> /etc/postgresql/$PGVERSION/main/pg_hba.conf
- - sudo install -o postgres -g postgres -m 600 -t /var/lib/postgresql/$PGVERSION/main/ certs/server.key certs/server.crt certs/root.crt
- - sudo bash -c "[[ '${PGVERSION}' < '9.2' ]] || (echo \"ssl_cert_file = 'server.crt'\" >> /etc/postgresql/$PGVERSION/main/postgresql.conf)"
- - sudo bash -c "[[ '${PGVERSION}' < '9.2' ]] || (echo \"ssl_key_file = 'server.key'\" >> /etc/postgresql/$PGVERSION/main/postgresql.conf)"
- - sudo bash -c "[[ '${PGVERSION}' < '9.2' ]] || (echo \"ssl_ca_file = 'root.crt'\" >> /etc/postgresql/$PGVERSION/main/postgresql.conf)"
- - sudo sh -c "echo 127.0.0.1 postgres >> /etc/hosts"
- - sudo ls -l /var/lib/postgresql/$PGVERSION/main/
- - sudo cat /etc/postgresql/$PGVERSION/main/postgresql.conf
- - sudo chmod 600 $PQSSLCERTTEST_PATH/postgresql.key
- - sudo /etc/init.d/postgresql restart
-
-env:
- global:
- - PGUSER=postgres
- - PQGOSSLTESTS=1
- - PQSSLCERTTEST_PATH=$PWD/certs
- - PGHOST=127.0.0.1
- matrix:
- - PGVERSION=9.4 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=9.3 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=9.2 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=9.1 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=9.0 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=8.4 PQTEST_BINARY_PARAMETERS=yes
- - PGVERSION=9.4 PQTEST_BINARY_PARAMETERS=no
- - PGVERSION=9.3 PQTEST_BINARY_PARAMETERS=no
- - PGVERSION=9.2 PQTEST_BINARY_PARAMETERS=no
- - PGVERSION=9.1 PQTEST_BINARY_PARAMETERS=no
- - PGVERSION=9.0 PQTEST_BINARY_PARAMETERS=no
- - PGVERSION=8.4 PQTEST_BINARY_PARAMETERS=no
-
-script:
- - go test -v ./...
-
-before_script:
- - psql -c 'create database pqgotest' -U postgres
- - psql -c 'create user pqgossltest' -U postgres
- - psql -c 'create user pqgosslcert' -U postgres
diff --git a/Godeps/_workspace/src/github.com/lib/pq/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/lib/pq/CONTRIBUTING.md
deleted file mode 100644
index 84c937f15..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/CONTRIBUTING.md
+++ /dev/null
@@ -1,29 +0,0 @@
-## Contributing to pq
-
-`pq` has a backlog of pull requests, but contributions are still very
-much welcome. You can help with patch review, submitting bug reports,
-or adding new functionality. There is no formal style guide, but
-please conform to the style of existing code and general Go formatting
-conventions when submitting patches.
-
-### Patch review
-
-Help review existing open pull requests by commenting on the code or
-proposed functionality.
-
-### Bug reports
-
-We appreciate any bug reports, but especially ones with self-contained
-(doesn't depend on code outside of pq), minimal (can't be simplified
-further) test cases. It's especially helpful if you can submit a pull
-request with just the failing test case (you'll probably want to
-pattern it after the tests in
-[conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go).
-
-### New functionality
-
-There are a number of pending patches for new functionality, so
-additional feature patches will take a while to merge. Still, patches
-are generally reviewed based on usefulness and complexity in addition
-to time-in-queue, so if you have a knockout idea, take a shot. Feel
-free to open an issue discussion your proposed patch beforehand.
diff --git a/Godeps/_workspace/src/github.com/lib/pq/LICENSE.md b/Godeps/_workspace/src/github.com/lib/pq/LICENSE.md
deleted file mode 100644
index 5773904a3..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/LICENSE.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Copyright (c) 2011-2013, 'pq' Contributors
-Portions Copyright (C) 2011 Blake Mizerany
-
-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.
diff --git a/Godeps/_workspace/src/github.com/lib/pq/README.md b/Godeps/_workspace/src/github.com/lib/pq/README.md
deleted file mode 100644
index 358d644f6..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/README.md
+++ /dev/null
@@ -1,103 +0,0 @@
-# pq - A pure Go postgres driver for Go's database/sql package
-
-[![Build Status](https://travis-ci.org/lib/pq.png?branch=master)](https://travis-ci.org/lib/pq)
-
-## Install
-
- go get github.com/lib/pq
-
-## Docs
-
-For detailed documentation and basic usage examples, please see the package
-documentation at <http://godoc.org/github.com/lib/pq>.
-
-## Tests
-
-`go test` is used for testing. A running PostgreSQL server is
-required, with the ability to log in. The default database to connect
-to test with is "pqgotest," but it can be overridden using environment
-variables.
-
-Example:
-
- PGHOST=/var/run/postgresql go test github.com/lib/pq
-
-Optionally, a benchmark suite can be run as part of the tests:
-
- PGHOST=/var/run/postgresql go test -bench .
-
-## Features
-
-* SSL
-* Handles bad connections for `database/sql`
-* Scan `time.Time` correctly (i.e. `timestamp[tz]`, `time[tz]`, `date`)
-* Scan binary blobs correctly (i.e. `bytea`)
-* Package for `hstore` support
-* COPY FROM support
-* pq.ParseURL for converting urls to connection strings for sql.Open.
-* Many libpq compatible environment variables
-* Unix socket support
-* Notifications: `LISTEN`/`NOTIFY`
-
-## Future / Things you can help with
-
-* Better COPY FROM / COPY TO (see discussion in #181)
-
-## Thank you (alphabetical)
-
-Some of these contributors are from the original library `bmizerany/pq.go` whose
-code still exists in here.
-
-* Andy Balholm (andybalholm)
-* Ben Berkert (benburkert)
-* Benjamin Heatwole (bheatwole)
-* Bill Mill (llimllib)
-* Bjørn Madsen (aeons)
-* Blake Gentry (bgentry)
-* Brad Fitzpatrick (bradfitz)
-* Charlie Melbye (cmelbye)
-* Chris Bandy (cbandy)
-* Chris Gilling (cgilling)
-* Chris Walsh (cwds)
-* Dan Sosedoff (sosedoff)
-* Daniel Farina (fdr)
-* Eric Chlebek (echlebek)
-* Eric Garrido (minusnine)
-* Eric Urban (hydrogen18)
-* Everyone at The Go Team
-* Evan Shaw (edsrzf)
-* Ewan Chou (coocood)
-* Federico Romero (federomero)
-* Fumin (fumin)
-* Gary Burd (garyburd)
-* Heroku (heroku)
-* James Pozdena (jpoz)
-* Jason McVetta (jmcvetta)
-* Jeremy Jay (pbnjay)
-* Joakim Sernbrant (serbaut)
-* John Gallagher (jgallagher)
-* Jonathan Rudenberg (titanous)
-* Joël Stemmer (jstemmer)
-* Kamil Kisiel (kisielk)
-* Kelly Dunn (kellydunn)
-* Keith Rarick (kr)
-* Kir Shatrov (kirs)
-* Lann Martin (lann)
-* Maciek Sakrejda (deafbybeheading)
-* Marc Brinkmann (mbr)
-* Marko Tiikkaja (johto)
-* Matt Newberry (MattNewberry)
-* Matt Robenolt (mattrobenolt)
-* Martin Olsen (martinolsen)
-* Mike Lewis (mikelikespie)
-* Nicolas Patry (Narsil)
-* Oliver Tonnhofer (olt)
-* Patrick Hayes (phayes)
-* Paul Hammond (paulhammond)
-* Ryan Smith (ryandotsmith)
-* Samuel Stauffer (samuel)
-* Timothée Peignier (cyberdelia)
-* Travis Cline (tmc)
-* TruongSinh Tran-Nguyen (truongsinh)
-* Yaismel Miranda (ympons)
-* notedit (notedit)
diff --git a/Godeps/_workspace/src/github.com/lib/pq/buf.go b/Godeps/_workspace/src/github.com/lib/pq/buf.go
deleted file mode 100644
index 666b0012a..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/buf.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package pq
-
-import (
- "bytes"
- "encoding/binary"
-
- "github.com/lib/pq/oid"
-)
-
-type readBuf []byte
-
-func (b *readBuf) int32() (n int) {
- n = int(int32(binary.BigEndian.Uint32(*b)))
- *b = (*b)[4:]
- return
-}
-
-func (b *readBuf) oid() (n oid.Oid) {
- n = oid.Oid(binary.BigEndian.Uint32(*b))
- *b = (*b)[4:]
- return
-}
-
-// N.B: this is actually an unsigned 16-bit integer, unlike int32
-func (b *readBuf) int16() (n int) {
- n = int(binary.BigEndian.Uint16(*b))
- *b = (*b)[2:]
- return
-}
-
-func (b *readBuf) string() string {
- i := bytes.IndexByte(*b, 0)
- if i < 0 {
- errorf("invalid message format; expected string terminator")
- }
- s := (*b)[:i]
- *b = (*b)[i+1:]
- return string(s)
-}
-
-func (b *readBuf) next(n int) (v []byte) {
- v = (*b)[:n]
- *b = (*b)[n:]
- return
-}
-
-func (b *readBuf) byte() byte {
- return b.next(1)[0]
-}
-
-type writeBuf struct {
- buf []byte
- pos int
-}
-
-func (b *writeBuf) int32(n int) {
- x := make([]byte, 4)
- binary.BigEndian.PutUint32(x, uint32(n))
- b.buf = append(b.buf, x...)
-}
-
-func (b *writeBuf) int16(n int) {
- x := make([]byte, 2)
- binary.BigEndian.PutUint16(x, uint16(n))
- b.buf = append(b.buf, x...)
-}
-
-func (b *writeBuf) string(s string) {
- b.buf = append(b.buf, (s + "\000")...)
-}
-
-func (b *writeBuf) byte(c byte) {
- b.buf = append(b.buf, c)
-}
-
-func (b *writeBuf) bytes(v []byte) {
- b.buf = append(b.buf, v...)
-}
-
-func (b *writeBuf) wrap() []byte {
- p := b.buf[b.pos:]
- binary.BigEndian.PutUint32(p, uint32(len(p)))
- return b.buf
-}
-
-func (b *writeBuf) next(c byte) {
- p := b.buf[b.pos:]
- binary.BigEndian.PutUint32(p, uint32(len(p)))
- b.pos = len(b.buf) + 1
- b.buf = append(b.buf, c, 0, 0, 0, 0)
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/README b/Godeps/_workspace/src/github.com/lib/pq/certs/README
deleted file mode 100644
index 24ab7b256..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains certificates and private keys for testing some
-SSL-related functionality in Travis. Do NOT use these certificates for
-anything other than testing.
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.crt b/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.crt
deleted file mode 100644
index 6e6b4284a..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.crt
+++ /dev/null
@@ -1,69 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Nevada, L=Las Vegas, O=github.com/lib/pq, CN=pq CA
- Validity
- Not Before: Oct 11 15:10:11 2014 GMT
- Not After : Oct 8 15:10:11 2024 GMT
- Subject: C=US, ST=Nevada, L=Las Vegas, O=github.com/lib/pq, CN=pqgosslcert
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:e3:8c:06:9a:70:54:51:d1:34:34:83:39:cd:a2:
- 59:0f:05:ed:8d:d8:0e:34:d0:92:f4:09:4d:ee:8c:
- 78:55:49:24:f8:3c:e0:34:58:02:b2:e7:94:58:c1:
- e8:e5:bb:d1:af:f6:54:c1:40:b1:90:70:79:0d:35:
- 54:9c:8f:16:e9:c2:f0:92:e6:64:49:38:c1:76:f8:
- 47:66:c4:5b:4a:b6:a9:43:ce:c8:be:6c:4d:2b:94:
- 97:3c:55:bc:d1:d0:6e:b7:53:ae:89:5c:4b:6b:86:
- 40:be:c1:ae:1e:64:ce:9c:ae:87:0a:69:e5:c8:21:
- 12:be:ae:1d:f6:45:df:16:a7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 9B:25:31:63:A2:D8:06:FF:CB:E3:E9:96:FF:0D:BA:DC:12:7D:04:CF
- X509v3 Authority Key Identifier:
- keyid:52:93:ED:1E:76:0A:9F:65:4F:DE:19:66:C1:D5:22:40:35:CB:A0:72
-
- X509v3 Basic Constraints:
- CA:FALSE
- X509v3 Key Usage:
- Digital Signature, Non Repudiation, Key Encipherment
- Signature Algorithm: sha256WithRSAEncryption
- 3e:f5:f8:0b:4e:11:bd:00:86:1f:ce:dc:97:02:98:91:11:f5:
- 65:f6:f2:8a:b2:3e:47:92:05:69:28:c9:e9:b4:f7:cf:93:d1:
- 2d:81:5d:00:3c:23:be:da:70:ea:59:e1:2c:d3:25:49:ae:a6:
- 95:54:c1:10:df:23:e3:fe:d6:e4:76:c7:6b:73:ad:1b:34:7c:
- e2:56:cc:c0:37:ae:c5:7a:11:20:6c:3d:05:0e:99:cd:22:6c:
- cf:59:a1:da:28:d4:65:ba:7d:2f:2b:3d:69:6d:a6:c1:ae:57:
- bf:56:64:13:79:f8:48:46:65:eb:81:67:28:0b:7b:de:47:10:
- b3:80:3c:31:d1:58:94:01:51:4a:c7:c8:1a:01:a8:af:c4:cd:
- bb:84:a5:d9:8b:b4:b9:a1:64:3e:95:d9:90:1d:d5:3f:67:cc:
- 3b:ba:f5:b4:d1:33:77:ee:c2:d2:3e:7e:c5:66:6e:b7:35:4c:
- 60:57:b0:b8:be:36:c8:f3:d3:95:8c:28:4a:c9:f7:27:a4:0d:
- e5:96:99:eb:f5:c8:bd:f3:84:6d:ef:02:f9:8a:36:7d:6b:5f:
- 36:68:37:41:d9:74:ae:c6:78:2e:44:86:a1:ad:43:ca:fb:b5:
- 3e:ba:10:23:09:02:ac:62:d1:d0:83:c8:95:b9:e3:5e:30:ff:
- 5b:2b:38:fa
------BEGIN CERTIFICATE-----
-MIIDEzCCAfugAwIBAgIBAjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEP
-MA0GA1UECBMGTmV2YWRhMRIwEAYDVQQHEwlMYXMgVmVnYXMxGjAYBgNVBAoTEWdp
-dGh1Yi5jb20vbGliL3BxMQ4wDAYDVQQDEwVwcSBDQTAeFw0xNDEwMTExNTEwMTFa
-Fw0yNDEwMDgxNTEwMTFaMGQxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZOZXZhZGEx
-EjAQBgNVBAcTCUxhcyBWZWdhczEaMBgGA1UEChMRZ2l0aHViLmNvbS9saWIvcHEx
-FDASBgNVBAMTC3BxZ29zc2xjZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDjjAaacFRR0TQ0gznNolkPBe2N2A400JL0CU3ujHhVSST4POA0WAKy55RYwejl
-u9Gv9lTBQLGQcHkNNVScjxbpwvCS5mRJOMF2+EdmxFtKtqlDzsi+bE0rlJc8VbzR
-0G63U66JXEtrhkC+wa4eZM6crocKaeXIIRK+rh32Rd8WpwIDAQABo1owWDAdBgNV
-HQ4EFgQUmyUxY6LYBv/L4+mW/w263BJ9BM8wHwYDVR0jBBgwFoAUUpPtHnYKn2VP
-3hlmwdUiQDXLoHIwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEL
-BQADggEBAD71+AtOEb0Ahh/O3JcCmJER9WX28oqyPkeSBWkoyem098+T0S2BXQA8
-I77acOpZ4SzTJUmuppVUwRDfI+P+1uR2x2tzrRs0fOJWzMA3rsV6ESBsPQUOmc0i
-bM9Zodoo1GW6fS8rPWltpsGuV79WZBN5+EhGZeuBZygLe95HELOAPDHRWJQBUUrH
-yBoBqK/EzbuEpdmLtLmhZD6V2ZAd1T9nzDu69bTRM3fuwtI+fsVmbrc1TGBXsLi+
-Nsjz05WMKErJ9yekDeWWmev1yL3zhG3vAvmKNn1rXzZoN0HZdK7GeC5EhqGtQ8r7
-tT66ECMJAqxi0dCDyJW5414w/1srOPo=
------END CERTIFICATE-----
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.key b/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.key
deleted file mode 100644
index eb8b20be9..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.key
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDjjAaacFRR0TQ0gznNolkPBe2N2A400JL0CU3ujHhVSST4POA0
-WAKy55RYwejlu9Gv9lTBQLGQcHkNNVScjxbpwvCS5mRJOMF2+EdmxFtKtqlDzsi+
-bE0rlJc8VbzR0G63U66JXEtrhkC+wa4eZM6crocKaeXIIRK+rh32Rd8WpwIDAQAB
-AoGAM5dM6/kp9P700i8qjOgRPym96Zoh5nGfz/rIE5z/r36NBkdvIg8OVZfR96nH
-b0b9TOMR5lsPp0sI9yivTWvX6qyvLJRWy2vvx17hXK9NxXUNTAm0PYZUTvCtcPeX
-RnJpzQKNZQPkFzF0uXBc4CtPK2Vz0+FGvAelrhYAxnw1dIkCQQD+9qaW5QhXjsjb
-Nl85CmXgxPmGROcgLQCO+omfrjf9UXrituU9Dz6auym5lDGEdMFnkzfr+wpasEy9
-mf5ZZOhDAkEA5HjXfVGaCtpydOt6hDon/uZsyssCK2lQ7NSuE3vP+sUsYMzIpEoy
-t3VWXqKbo+g9KNDTP4WEliqp1aiSIylzzQJANPeqzihQnlgEdD4MdD4rwhFJwVIp
-Le8Lcais1KaN7StzOwxB/XhgSibd2TbnPpw+3bSg5n5lvUdo+e62/31OHwJAU1jS
-I+F09KikQIr28u3UUWT2IzTT4cpVv1AHAQyV3sG3YsjSGT0IK20eyP9BEBZU2WL0
-7aNjrvR5aHxKc5FXsQJABsFtyGpgI5X4xufkJZVZ+Mklz2n7iXa+XPatMAHFxAtb
-EEMt60rngwMjXAzBSC6OYuYogRRAY3UCacNC5VhLYQ==
------END RSA PRIVATE KEY-----
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/root.crt b/Godeps/_workspace/src/github.com/lib/pq/certs/root.crt
deleted file mode 100644
index aecf8f621..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/root.crt
+++ /dev/null
@@ -1,24 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIJANmheROCdW1NMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNV
-BAYTAlVTMQ8wDQYDVQQIEwZOZXZhZGExEjAQBgNVBAcTCUxhcyBWZWdhczEaMBgG
-A1UEChMRZ2l0aHViLmNvbS9saWIvcHExDjAMBgNVBAMTBXBxIENBMB4XDTE0MTAx
-MTE1MDQyOVoXDTI0MTAwODE1MDQyOVowXjELMAkGA1UEBhMCVVMxDzANBgNVBAgT
-Bk5ldmFkYTESMBAGA1UEBxMJTGFzIFZlZ2FzMRowGAYDVQQKExFnaXRodWIuY29t
-L2xpYi9wcTEOMAwGA1UEAxMFcHEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCV4PxP7ShzWBzUCThcKk3qZtOLtHmszQVtbqhvgTpm1kTRtKBdVMu0
-pLAHQ3JgJCnAYgH0iZxVGoMP16T3irdgsdC48+nNTFM2T0cCdkfDURGIhSFN47cb
-Pgy306BcDUD2q7ucW33+dlFSRuGVewocoh4BWM/vMtMvvWzdi4Ag/L/jhb+5wZxZ
-sWymsadOVSDePEMKOvlCa3EdVwVFV40TVyDb+iWBUivDAYsS2a3KajuJrO6MbZiE
-Sp2RCIkZS2zFmzWxVRi9ZhzIZhh7EVF9JAaNC3T52jhGUdlRq3YpBTMnd89iOh74
-6jWXG7wSuPj3haFzyNhmJ0ZUh+2Ynoh1AgMBAAGjgcMwgcAwHQYDVR0OBBYEFFKT
-7R52Cp9lT94ZZsHVIkA1y6ByMIGQBgNVHSMEgYgwgYWAFFKT7R52Cp9lT94ZZsHV
-IkA1y6ByoWKkYDBeMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGTmV2YWRhMRIwEAYD
-VQQHEwlMYXMgVmVnYXMxGjAYBgNVBAoTEWdpdGh1Yi5jb20vbGliL3BxMQ4wDAYD
-VQQDEwVwcSBDQYIJANmheROCdW1NMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
-BQADggEBAAEhCLWkqJNMI8b4gkbmj5fqQ/4+oO83bZ3w2Oqf6eZ8I8BC4f2NOyE6
-tRUlq5+aU7eqC1cOAvGjO+YHN/bF/DFpwLlzvUSXt+JP/pYcUjL7v+pIvwqec9hD
-ndvM4iIbkD/H/OYQ3L+N3W+G1x7AcFIX+bGCb3PzYVQAjxreV6//wgKBosMGFbZo
-HPxT9RPMun61SViF04H5TNs0derVn1+5eiiYENeAhJzQNyZoOOUuX1X/Inx9bEPh
-C5vFBtSMgIytPgieRJVWAiMLYsfpIAStrHztRAbBs2DU01LmMgRvHdxgFEKinC/d
-UHZZQDP+6pT+zADrGhQGXe4eThaO6f0=
------END CERTIFICATE-----
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/server.crt b/Godeps/_workspace/src/github.com/lib/pq/certs/server.crt
deleted file mode 100644
index ddc995a6d..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/server.crt
+++ /dev/null
@@ -1,81 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Nevada, L=Las Vegas, O=github.com/lib/pq, CN=pq CA
- Validity
- Not Before: Oct 11 15:05:15 2014 GMT
- Not After : Oct 8 15:05:15 2024 GMT
- Subject: C=US, ST=Nevada, L=Las Vegas, O=github.com/lib/pq, CN=postgres
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (2048 bit)
- Modulus (2048 bit):
- 00:d7:8a:4c:85:fb:17:a5:3c:8f:e0:72:11:29:ce:
- 3f:b0:1f:3f:7d:c6:ee:7f:a7:fc:02:2b:35:47:08:
- a6:3d:90:df:5c:56:14:94:00:c7:6d:d1:d2:e2:61:
- 95:77:b8:e3:a6:66:31:f9:1f:21:7d:62:e1:27:da:
- 94:37:61:4a:ea:63:53:a0:61:b8:9c:bb:a5:e2:e7:
- b7:a6:d8:0f:05:04:c7:29:e2:ea:49:2b:7f:de:15:
- 00:a6:18:70:50:c7:0c:de:9a:f9:5a:96:b0:e1:94:
- 06:c6:6d:4a:21:3b:b4:0f:a5:6d:92:86:34:b2:4e:
- d7:0e:a7:19:c0:77:0b:7b:87:c8:92:de:42:ff:86:
- d2:b7:9a:a4:d4:15:23:ca:ad:a5:69:21:b8:ce:7e:
- 66:cb:85:5d:b9:ed:8b:2d:09:8d:94:e4:04:1e:72:
- ec:ef:d0:76:90:15:5a:a4:f7:91:4b:e9:ce:4e:9d:
- 5d:9a:70:17:9c:d8:e9:73:83:ea:3d:61:99:a6:cd:
- ac:91:40:5a:88:77:e5:4e:2a:8e:3d:13:f3:f9:38:
- 6f:81:6b:8a:95:ca:0e:07:ab:6f:da:b4:8c:d9:ff:
- aa:78:03:aa:c7:c2:cf:6f:64:92:d3:d8:83:d5:af:
- f1:23:18:a7:2e:7b:17:0b:e7:7d:f1:fa:a8:41:a3:
- 04:57
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- EE:F0:B3:46:DC:C7:09:EB:0E:B6:2F:E5:FE:62:60:45:44:9F:59:CC
- X509v3 Authority Key Identifier:
- keyid:52:93:ED:1E:76:0A:9F:65:4F:DE:19:66:C1:D5:22:40:35:CB:A0:72
-
- X509v3 Basic Constraints:
- CA:FALSE
- X509v3 Key Usage:
- Digital Signature, Non Repudiation, Key Encipherment
- Signature Algorithm: sha256WithRSAEncryption
- 7e:5a:6e:be:bf:d2:6c:c1:d6:fa:b6:fb:3f:06:53:36:08:87:
- 9d:95:b1:39:af:9e:f6:47:38:17:39:da:25:7c:f2:ad:0c:e3:
- ab:74:19:ca:fb:8c:a0:50:c0:1d:19:8a:9c:21:ed:0f:3a:d1:
- 96:54:2e:10:09:4f:b8:70:f7:2b:99:43:d2:c6:15:bc:3f:24:
- 7d:28:39:32:3f:8d:a4:4f:40:75:7f:3e:0d:1c:d1:69:f2:4e:
- 98:83:47:97:d2:25:ac:c9:36:86:2f:04:a6:c4:86:c7:c4:00:
- 5f:7f:b9:ad:fc:bf:e9:f5:78:d7:82:1a:51:0d:fc:ab:9e:92:
- 1d:5f:0c:18:d1:82:e0:14:c9:ce:91:89:71:ff:49:49:ff:35:
- bf:7b:44:78:42:c1:d0:66:65:bb:28:2e:60:ca:9b:20:12:a9:
- 90:61:b1:96:ec:15:46:c9:37:f7:07:90:8a:89:45:2a:3f:37:
- ec:dc:e3:e5:8f:c3:3a:57:80:a5:54:60:0c:e1:b2:26:99:2b:
- 40:7e:36:d1:9a:70:02:ec:63:f4:3b:72:ae:81:fb:30:20:6d:
- cb:48:46:c6:b5:8f:39:b1:84:05:25:55:8d:f5:62:f6:1b:46:
- 2e:da:a3:4c:26:12:44:d7:56:b6:b8:a9:ca:d3:ab:71:45:7c:
- 9f:48:6d:1e
------BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEP
-MA0GA1UECBMGTmV2YWRhMRIwEAYDVQQHEwlMYXMgVmVnYXMxGjAYBgNVBAoTEWdp
-dGh1Yi5jb20vbGliL3BxMQ4wDAYDVQQDEwVwcSBDQTAeFw0xNDEwMTExNTA1MTVa
-Fw0yNDEwMDgxNTA1MTVaMGExCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZOZXZhZGEx
-EjAQBgNVBAcTCUxhcyBWZWdhczEaMBgGA1UEChMRZ2l0aHViLmNvbS9saWIvcHEx
-ETAPBgNVBAMTCHBvc3RncmVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA14pMhfsXpTyP4HIRKc4/sB8/fcbuf6f8Ais1RwimPZDfXFYUlADHbdHS4mGV
-d7jjpmYx+R8hfWLhJ9qUN2FK6mNToGG4nLul4ue3ptgPBQTHKeLqSSt/3hUAphhw
-UMcM3pr5Wpaw4ZQGxm1KITu0D6VtkoY0sk7XDqcZwHcLe4fIkt5C/4bSt5qk1BUj
-yq2laSG4zn5my4Vdue2LLQmNlOQEHnLs79B2kBVapPeRS+nOTp1dmnAXnNjpc4Pq
-PWGZps2skUBaiHflTiqOPRPz+ThvgWuKlcoOB6tv2rSM2f+qeAOqx8LPb2SS09iD
-1a/xIxinLnsXC+d98fqoQaMEVwIDAQABo1owWDAdBgNVHQ4EFgQU7vCzRtzHCesO
-ti/l/mJgRUSfWcwwHwYDVR0jBBgwFoAUUpPtHnYKn2VP3hlmwdUiQDXLoHIwCQYD
-VR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQELBQADggEBAH5abr6/0mzB
-1vq2+z8GUzYIh52VsTmvnvZHOBc52iV88q0M46t0Gcr7jKBQwB0Zipwh7Q860ZZU
-LhAJT7hw9yuZQ9LGFbw/JH0oOTI/jaRPQHV/Pg0c0WnyTpiDR5fSJazJNoYvBKbE
-hsfEAF9/ua38v+n1eNeCGlEN/Kuekh1fDBjRguAUyc6RiXH/SUn/Nb97RHhCwdBm
-ZbsoLmDKmyASqZBhsZbsFUbJN/cHkIqJRSo/N+zc4+WPwzpXgKVUYAzhsiaZK0B+
-NtGacALsY/Q7cq6B+zAgbctIRsa1jzmxhAUlVY31YvYbRi7ao0wmEkTXVra4qcrT
-q3FFfJ9IbR4=
------END CERTIFICATE-----
diff --git a/Godeps/_workspace/src/github.com/lib/pq/certs/server.key b/Godeps/_workspace/src/github.com/lib/pq/certs/server.key
deleted file mode 100644
index bd7b019b6..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/certs/server.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEA14pMhfsXpTyP4HIRKc4/sB8/fcbuf6f8Ais1RwimPZDfXFYU
-lADHbdHS4mGVd7jjpmYx+R8hfWLhJ9qUN2FK6mNToGG4nLul4ue3ptgPBQTHKeLq
-SSt/3hUAphhwUMcM3pr5Wpaw4ZQGxm1KITu0D6VtkoY0sk7XDqcZwHcLe4fIkt5C
-/4bSt5qk1BUjyq2laSG4zn5my4Vdue2LLQmNlOQEHnLs79B2kBVapPeRS+nOTp1d
-mnAXnNjpc4PqPWGZps2skUBaiHflTiqOPRPz+ThvgWuKlcoOB6tv2rSM2f+qeAOq
-x8LPb2SS09iD1a/xIxinLnsXC+d98fqoQaMEVwIDAQABAoIBAF3ZoihUhJ82F4+r
-Gz4QyDpv4L1reT2sb1aiabhcU8ZK5nbWJG+tRyjSS/i2dNaEcttpdCj9HR/zhgZM
-bm0OuAgG58rVwgS80CZUruq++Qs+YVojq8/gWPTiQD4SNhV2Fmx3HkwLgUk3oxuT
-SsvdqzGE3okGVrutCIcgy126eA147VPMoej1Bb3fO6npqK0pFPhZfAc0YoqJuM+k
-obRm5pAnGUipyLCFXjA9HYPKwYZw2RtfdA3CiImHeanSdqS+ctrC9y8BV40Th7gZ
-haXdKUNdjmIxV695QQ1mkGqpKLZFqhzKioGQ2/Ly2d1iaKN9fZltTusu8unepWJ2
-tlT9qMECgYEA9uHaF1t2CqE+AJvWTihHhPIIuLxoOQXYea1qvxfcH/UMtaLKzCNm
-lQ5pqCGsPvp+10f36yttO1ZehIvlVNXuJsjt0zJmPtIolNuJY76yeussfQ9jHheB
-5uPEzCFlHzxYbBUyqgWaF6W74okRGzEGJXjYSP0yHPPdU4ep2q3bGiUCgYEA34Af
-wBSuQSK7uLxArWHvQhyuvi43ZGXls6oRGl+Ysj54s8BP6XGkq9hEJ6G4yxgyV+BR
-DUOs5X8/TLT8POuIMYvKTQthQyCk0eLv2FLdESDuuKx0kBVY3s8lK3/z5HhrdOiN
-VMNZU+xDKgKc3hN9ypkk8vcZe6EtH7Y14e0rVcsCgYBTgxi8F/M5K0wG9rAqphNz
-VFBA9XKn/2M33cKjO5X5tXIEKzpAjaUQvNxexG04rJGljzG8+mar0M6ONahw5yD1
-O7i/XWgazgpuOEkkVYiYbd8RutfDgR4vFVMn3hAP3eDnRtBplRWH9Ec3HTiNIys6
-F8PKBOQjyRZQQC7jyzW3hQKBgACe5HeuFwXLSOYsb6mLmhR+6+VPT4wR1F95W27N
-USk9jyxAnngxfpmTkiziABdgS9N+pfr5cyN4BP77ia/Jn6kzkC5Cl9SN5KdIkA3z
-vPVtN/x/ThuQU5zaymmig1ThGLtMYggYOslG4LDfLPxY5YKIhle+Y+259twdr2yf
-Mf2dAoGAaGv3tWMgnIdGRk6EQL/yb9PKHo7ShN+tKNlGaK7WwzBdKs+Fe8jkgcr7
-pz4Ne887CmxejdISzOCcdT+Zm9Bx6I/uZwWOtDvWpIgIxVX9a9URj/+D1MxTE/y4
-d6H+c89yDY62I2+drMpdjCd3EtCaTlxpTbRS+s1eAHMH7aEkcCE=
------END RSA PRIVATE KEY-----
diff --git a/Godeps/_workspace/src/github.com/lib/pq/conn.go b/Godeps/_workspace/src/github.com/lib/pq/conn.go
deleted file mode 100644
index 4af880fb5..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/conn.go
+++ /dev/null
@@ -1,1777 +0,0 @@
-package pq
-
-import (
- "bufio"
- "crypto/md5"
- "crypto/tls"
- "crypto/x509"
- "database/sql"
- "database/sql/driver"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "os"
- "os/user"
- "path"
- "path/filepath"
- "strconv"
- "strings"
- "time"
- "unicode"
-
- "github.com/lib/pq/oid"
-)
-
-// Common error types
-var (
- ErrNotSupported = errors.New("pq: Unsupported command")
- ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction")
- ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server")
- ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less.")
- ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly.")
-)
-
-type drv struct{}
-
-func (d *drv) Open(name string) (driver.Conn, error) {
- return Open(name)
-}
-
-func init() {
- sql.Register("postgres", &drv{})
-}
-
-type parameterStatus struct {
- // server version in the same format as server_version_num, or 0 if
- // unavailable
- serverVersion int
-
- // the current location based on the TimeZone value of the session, if
- // available
- currentLocation *time.Location
-}
-
-type transactionStatus byte
-
-const (
- txnStatusIdle transactionStatus = 'I'
- txnStatusIdleInTransaction transactionStatus = 'T'
- txnStatusInFailedTransaction transactionStatus = 'E'
-)
-
-func (s transactionStatus) String() string {
- switch s {
- case txnStatusIdle:
- return "idle"
- case txnStatusIdleInTransaction:
- return "idle in transaction"
- case txnStatusInFailedTransaction:
- return "in a failed transaction"
- default:
- errorf("unknown transactionStatus %d", s)
- }
-
- panic("not reached")
-}
-
-type Dialer interface {
- Dial(network, address string) (net.Conn, error)
- DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
-}
-
-type defaultDialer struct{}
-
-func (d defaultDialer) Dial(ntw, addr string) (net.Conn, error) {
- return net.Dial(ntw, addr)
-}
-func (d defaultDialer) DialTimeout(ntw, addr string, timeout time.Duration) (net.Conn, error) {
- return net.DialTimeout(ntw, addr, timeout)
-}
-
-type conn struct {
- c net.Conn
- buf *bufio.Reader
- namei int
- scratch [512]byte
- txnStatus transactionStatus
-
- parameterStatus parameterStatus
-
- saveMessageType byte
- saveMessageBuffer []byte
-
- // If true, this connection is bad and all public-facing functions should
- // return ErrBadConn.
- bad bool
-
- // If set, this connection should never use the binary format when
- // receiving query results from prepared statements. Only provided for
- // debugging.
- disablePreparedBinaryResult bool
-
- // Whether to always send []byte parameters over as binary. Enables single
- // round-trip mode for non-prepared Query calls.
- binaryParameters bool
-}
-
-// Handle driver-side settings in parsed connection string.
-func (c *conn) handleDriverSettings(o values) (err error) {
- boolSetting := func(key string, val *bool) error {
- if value := o.Get(key); value != "" {
- if value == "yes" {
- *val = true
- } else if value == "no" {
- *val = false
- } else {
- return fmt.Errorf("unrecognized value %q for %s", value, key)
- }
- }
- return nil
- }
-
- err = boolSetting("disable_prepared_binary_result", &c.disablePreparedBinaryResult)
- if err != nil {
- return err
- }
- err = boolSetting("binary_parameters", &c.binaryParameters)
- if err != nil {
- return err
- }
- return nil
-}
-
-func (c *conn) writeBuf(b byte) *writeBuf {
- c.scratch[0] = b
- return &writeBuf{
- buf: c.scratch[:5],
- pos: 1,
- }
-}
-
-func Open(name string) (_ driver.Conn, err error) {
- return DialOpen(defaultDialer{}, name)
-}
-
-func DialOpen(d Dialer, name string) (_ driver.Conn, err error) {
- // Handle any panics during connection initialization. Note that we
- // specifically do *not* want to use errRecover(), as that would turn any
- // connection errors into ErrBadConns, hiding the real error message from
- // the user.
- defer errRecoverNoErrBadConn(&err)
-
- o := make(values)
-
- // A number of defaults are applied here, in this order:
- //
- // * Very low precedence defaults applied in every situation
- // * Environment variables
- // * Explicitly passed connection information
- o.Set("host", "localhost")
- o.Set("port", "5432")
- // N.B.: Extra float digits should be set to 3, but that breaks
- // Postgres 8.4 and older, where the max is 2.
- o.Set("extra_float_digits", "2")
- for k, v := range parseEnviron(os.Environ()) {
- o.Set(k, v)
- }
-
- if strings.HasPrefix(name, "postgres://") || strings.HasPrefix(name, "postgresql://") {
- name, err = ParseURL(name)
- if err != nil {
- return nil, err
- }
- }
-
- if err := parseOpts(name, o); err != nil {
- return nil, err
- }
-
- // Use the "fallback" application name if necessary
- if fallback := o.Get("fallback_application_name"); fallback != "" {
- if !o.Isset("application_name") {
- o.Set("application_name", fallback)
- }
- }
-
- // We can't work with any client_encoding other than UTF-8 currently.
- // However, we have historically allowed the user to set it to UTF-8
- // explicitly, and there's no reason to break such programs, so allow that.
- // Note that the "options" setting could also set client_encoding, but
- // parsing its value is not worth it. Instead, we always explicitly send
- // client_encoding as a separate run-time parameter, which should override
- // anything set in options.
- if enc := o.Get("client_encoding"); enc != "" && !isUTF8(enc) {
- return nil, errors.New("client_encoding must be absent or 'UTF8'")
- }
- o.Set("client_encoding", "UTF8")
- // DateStyle needs a similar treatment.
- if datestyle := o.Get("datestyle"); datestyle != "" {
- if datestyle != "ISO, MDY" {
- panic(fmt.Sprintf("setting datestyle must be absent or %v; got %v",
- "ISO, MDY", datestyle))
- }
- } else {
- o.Set("datestyle", "ISO, MDY")
- }
-
- // If a user is not provided by any other means, the last
- // resort is to use the current operating system provided user
- // name.
- if o.Get("user") == "" {
- u, err := userCurrent()
- if err != nil {
- return nil, err
- } else {
- o.Set("user", u)
- }
- }
-
- cn := &conn{}
- err = cn.handleDriverSettings(o)
- if err != nil {
- return nil, err
- }
-
- cn.c, err = dial(d, o)
- if err != nil {
- return nil, err
- }
- cn.ssl(o)
- cn.buf = bufio.NewReader(cn.c)
- cn.startup(o)
-
- // reset the deadline, in case one was set (see dial)
- if timeout := o.Get("connect_timeout"); timeout != "" && timeout != "0" {
- err = cn.c.SetDeadline(time.Time{})
- }
- return cn, err
-}
-
-func dial(d Dialer, o values) (net.Conn, error) {
- ntw, addr := network(o)
- // SSL is not necessary or supported over UNIX domain sockets
- if ntw == "unix" {
- o["sslmode"] = "disable"
- }
-
- // Zero or not specified means wait indefinitely.
- if timeout := o.Get("connect_timeout"); timeout != "" && timeout != "0" {
- seconds, err := strconv.ParseInt(timeout, 10, 0)
- if err != nil {
- return nil, fmt.Errorf("invalid value for parameter connect_timeout: %s", err)
- }
- duration := time.Duration(seconds) * time.Second
- // connect_timeout should apply to the entire connection establishment
- // procedure, so we both use a timeout for the TCP connection
- // establishment and set a deadline for doing the initial handshake.
- // The deadline is then reset after startup() is done.
- deadline := time.Now().Add(duration)
- conn, err := d.DialTimeout(ntw, addr, duration)
- if err != nil {
- return nil, err
- }
- err = conn.SetDeadline(deadline)
- return conn, err
- }
- return d.Dial(ntw, addr)
-}
-
-func network(o values) (string, string) {
- host := o.Get("host")
-
- if strings.HasPrefix(host, "/") {
- sockPath := path.Join(host, ".s.PGSQL."+o.Get("port"))
- return "unix", sockPath
- }
-
- return "tcp", host + ":" + o.Get("port")
-}
-
-type values map[string]string
-
-func (vs values) Set(k, v string) {
- vs[k] = v
-}
-
-func (vs values) Get(k string) (v string) {
- return vs[k]
-}
-
-func (vs values) Isset(k string) bool {
- _, ok := vs[k]
- return ok
-}
-
-// scanner implements a tokenizer for libpq-style option strings.
-type scanner struct {
- s []rune
- i int
-}
-
-// newScanner returns a new scanner initialized with the option string s.
-func newScanner(s string) *scanner {
- return &scanner{[]rune(s), 0}
-}
-
-// Next returns the next rune.
-// It returns 0, false if the end of the text has been reached.
-func (s *scanner) Next() (rune, bool) {
- if s.i >= len(s.s) {
- return 0, false
- }
- r := s.s[s.i]
- s.i++
- return r, true
-}
-
-// SkipSpaces returns the next non-whitespace rune.
-// It returns 0, false if the end of the text has been reached.
-func (s *scanner) SkipSpaces() (rune, bool) {
- r, ok := s.Next()
- for unicode.IsSpace(r) && ok {
- r, ok = s.Next()
- }
- return r, ok
-}
-
-// parseOpts parses the options from name and adds them to the values.
-//
-// The parsing code is based on conninfo_parse from libpq's fe-connect.c
-func parseOpts(name string, o values) error {
- s := newScanner(name)
-
- for {
- var (
- keyRunes, valRunes []rune
- r rune
- ok bool
- )
-
- if r, ok = s.SkipSpaces(); !ok {
- break
- }
-
- // Scan the key
- for !unicode.IsSpace(r) && r != '=' {
- keyRunes = append(keyRunes, r)
- if r, ok = s.Next(); !ok {
- break
- }
- }
-
- // Skip any whitespace if we're not at the = yet
- if r != '=' {
- r, ok = s.SkipSpaces()
- }
-
- // The current character should be =
- if r != '=' || !ok {
- return fmt.Errorf(`missing "=" after %q in connection info string"`, string(keyRunes))
- }
-
- // Skip any whitespace after the =
- if r, ok = s.SkipSpaces(); !ok {
- // If we reach the end here, the last value is just an empty string as per libpq.
- o.Set(string(keyRunes), "")
- break
- }
-
- if r != '\'' {
- for !unicode.IsSpace(r) {
- if r == '\\' {
- if r, ok = s.Next(); !ok {
- return fmt.Errorf(`missing character after backslash`)
- }
- }
- valRunes = append(valRunes, r)
-
- if r, ok = s.Next(); !ok {
- break
- }
- }
- } else {
- quote:
- for {
- if r, ok = s.Next(); !ok {
- return fmt.Errorf(`unterminated quoted string literal in connection string`)
- }
- switch r {
- case '\'':
- break quote
- case '\\':
- r, _ = s.Next()
- fallthrough
- default:
- valRunes = append(valRunes, r)
- }
- }
- }
-
- o.Set(string(keyRunes), string(valRunes))
- }
-
- return nil
-}
-
-func (cn *conn) isInTransaction() bool {
- return cn.txnStatus == txnStatusIdleInTransaction ||
- cn.txnStatus == txnStatusInFailedTransaction
-}
-
-func (cn *conn) checkIsInTransaction(intxn bool) {
- if cn.isInTransaction() != intxn {
- cn.bad = true
- errorf("unexpected transaction status %v", cn.txnStatus)
- }
-}
-
-func (cn *conn) Begin() (_ driver.Tx, err error) {
- if cn.bad {
- return nil, driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- cn.checkIsInTransaction(false)
- _, commandTag, err := cn.simpleExec("BEGIN")
- if err != nil {
- return nil, err
- }
- if commandTag != "BEGIN" {
- cn.bad = true
- return nil, fmt.Errorf("unexpected command tag %s", commandTag)
- }
- if cn.txnStatus != txnStatusIdleInTransaction {
- cn.bad = true
- return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus)
- }
- return cn, nil
-}
-
-func (cn *conn) Commit() (err error) {
- if cn.bad {
- return driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- cn.checkIsInTransaction(true)
- // We don't want the client to think that everything is okay if it tries
- // to commit a failed transaction. However, no matter what we return,
- // database/sql will release this connection back into the free connection
- // pool so we have to abort the current transaction here. Note that you
- // would get the same behaviour if you issued a COMMIT in a failed
- // transaction, so it's also the least surprising thing to do here.
- if cn.txnStatus == txnStatusInFailedTransaction {
- if err := cn.Rollback(); err != nil {
- return err
- }
- return ErrInFailedTransaction
- }
-
- _, commandTag, err := cn.simpleExec("COMMIT")
- if err != nil {
- if cn.isInTransaction() {
- cn.bad = true
- }
- return err
- }
- if commandTag != "COMMIT" {
- cn.bad = true
- return fmt.Errorf("unexpected command tag %s", commandTag)
- }
- cn.checkIsInTransaction(false)
- return nil
-}
-
-func (cn *conn) Rollback() (err error) {
- if cn.bad {
- return driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- cn.checkIsInTransaction(true)
- _, commandTag, err := cn.simpleExec("ROLLBACK")
- if err != nil {
- if cn.isInTransaction() {
- cn.bad = true
- }
- return err
- }
- if commandTag != "ROLLBACK" {
- return fmt.Errorf("unexpected command tag %s", commandTag)
- }
- cn.checkIsInTransaction(false)
- return nil
-}
-
-func (cn *conn) gname() string {
- cn.namei++
- return strconv.FormatInt(int64(cn.namei), 10)
-}
-
-func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err error) {
- b := cn.writeBuf('Q')
- b.string(q)
- cn.send(b)
-
- for {
- t, r := cn.recv1()
- switch t {
- case 'C':
- res, commandTag = cn.parseComplete(r.string())
- case 'Z':
- cn.processReadyForQuery(r)
- // done
- return
- case 'E':
- err = parseError(r)
- case 'T', 'D', 'I':
- // ignore any results
- default:
- cn.bad = true
- errorf("unknown response for simple query: %q", t)
- }
- }
-}
-
-func (cn *conn) simpleQuery(q string) (res *rows, err error) {
- defer cn.errRecover(&err)
-
- st := &stmt{cn: cn, name: ""}
-
- b := cn.writeBuf('Q')
- b.string(q)
- cn.send(b)
-
- for {
- t, r := cn.recv1()
- switch t {
- case 'C', 'I':
- // We allow queries which don't return any results through Query as
- // well as Exec. We still have to give database/sql a rows object
- // the user can close, though, to avoid connections from being
- // leaked. A "rows" with done=true works fine for that purpose.
- if err != nil {
- cn.bad = true
- errorf("unexpected message %q in simple query execution", t)
- }
- if res == nil {
- res = &rows{
- cn: cn,
- colNames: st.colNames,
- colTyps: st.colTyps,
- colFmts: st.colFmts,
- }
- }
- res.done = true
- case 'Z':
- cn.processReadyForQuery(r)
- // done
- return
- case 'E':
- res = nil
- err = parseError(r)
- case 'D':
- if res == nil {
- cn.bad = true
- errorf("unexpected DataRow in simple query execution")
- }
- // the query didn't fail; kick off to Next
- cn.saveMessage(t, r)
- return
- case 'T':
- // res might be non-nil here if we received a previous
- // CommandComplete, but that's fine; just overwrite it
- res = &rows{cn: cn}
- res.colNames, res.colFmts, res.colTyps = parsePortalRowDescribe(r)
-
- // To work around a bug in QueryRow in Go 1.2 and earlier, wait
- // until the first DataRow has been received.
- default:
- cn.bad = true
- errorf("unknown response for simple query: %q", t)
- }
- }
-}
-
-// Decides which column formats to use for a prepared statement. The input is
-// an array of type oids, one element per result column.
-func decideColumnFormats(colTyps []oid.Oid, forceText bool) (colFmts []format, colFmtData []byte) {
- if len(colTyps) == 0 {
- return nil, colFmtDataAllText
- }
-
- colFmts = make([]format, len(colTyps))
- if forceText {
- return colFmts, colFmtDataAllText
- }
-
- allBinary := true
- allText := true
- for i, o := range colTyps {
- switch o {
- // This is the list of types to use binary mode for when receiving them
- // through a prepared statement. If a type appears in this list, it
- // must also be implemented in binaryDecode in encode.go.
- case oid.T_bytea:
- fallthrough
- case oid.T_int8:
- fallthrough
- case oid.T_int4:
- fallthrough
- case oid.T_int2:
- colFmts[i] = formatBinary
- allText = false
-
- default:
- allBinary = false
- }
- }
-
- if allBinary {
- return colFmts, colFmtDataAllBinary
- } else if allText {
- return colFmts, colFmtDataAllText
- } else {
- colFmtData = make([]byte, 2+len(colFmts)*2)
- binary.BigEndian.PutUint16(colFmtData, uint16(len(colFmts)))
- for i, v := range colFmts {
- binary.BigEndian.PutUint16(colFmtData[2+i*2:], uint16(v))
- }
- return colFmts, colFmtData
- }
-}
-
-func (cn *conn) prepareTo(q, stmtName string) *stmt {
- st := &stmt{cn: cn, name: stmtName}
-
- b := cn.writeBuf('P')
- b.string(st.name)
- b.string(q)
- b.int16(0)
-
- b.next('D')
- b.byte('S')
- b.string(st.name)
-
- b.next('S')
- cn.send(b)
-
- cn.readParseResponse()
- st.paramTyps, st.colNames, st.colTyps = cn.readStatementDescribeResponse()
- st.colFmts, st.colFmtData = decideColumnFormats(st.colTyps, cn.disablePreparedBinaryResult)
- cn.readReadyForQuery()
- return st
-}
-
-func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) {
- if cn.bad {
- return nil, driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- if len(q) >= 4 && strings.EqualFold(q[:4], "COPY") {
- return cn.prepareCopyIn(q)
- }
- return cn.prepareTo(q, cn.gname()), nil
-}
-
-func (cn *conn) Close() (err error) {
- if cn.bad {
- return driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- // Don't go through send(); ListenerConn relies on us not scribbling on the
- // scratch buffer of this connection.
- err = cn.sendSimpleMessage('X')
- if err != nil {
- return err
- }
-
- return cn.c.Close()
-}
-
-// Implement the "Queryer" interface
-func (cn *conn) Query(query string, args []driver.Value) (_ driver.Rows, err error) {
- if cn.bad {
- return nil, driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- // Check to see if we can use the "simpleQuery" interface, which is
- // *much* faster than going through prepare/exec
- if len(args) == 0 {
- return cn.simpleQuery(query)
- }
-
- if cn.binaryParameters {
- cn.sendBinaryModeQuery(query, args)
-
- cn.readParseResponse()
- cn.readBindResponse()
- rows := &rows{cn: cn}
- rows.colNames, rows.colFmts, rows.colTyps = cn.readPortalDescribeResponse()
- cn.postExecuteWorkaround()
- return rows, nil
- } else {
- st := cn.prepareTo(query, "")
- st.exec(args)
- return &rows{
- cn: cn,
- colNames: st.colNames,
- colTyps: st.colTyps,
- colFmts: st.colFmts,
- }, nil
- }
-}
-
-// Implement the optional "Execer" interface for one-shot queries
-func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) {
- if cn.bad {
- return nil, driver.ErrBadConn
- }
- defer cn.errRecover(&err)
-
- // Check to see if we can use the "simpleExec" interface, which is
- // *much* faster than going through prepare/exec
- if len(args) == 0 {
- // ignore commandTag, our caller doesn't care
- r, _, err := cn.simpleExec(query)
- return r, err
- }
-
- if cn.binaryParameters {
- cn.sendBinaryModeQuery(query, args)
-
- cn.readParseResponse()
- cn.readBindResponse()
- cn.readPortalDescribeResponse()
- cn.postExecuteWorkaround()
- res, _, err = cn.readExecuteResponse("Execute")
- return res, err
- } else {
- // Use the unnamed statement to defer planning until bind
- // time, or else value-based selectivity estimates cannot be
- // used.
- st := cn.prepareTo(query, "")
- r, err := st.Exec(args)
- if err != nil {
- panic(err)
- }
- return r, err
- }
-}
-
-func (cn *conn) send(m *writeBuf) {
- _, err := cn.c.Write(m.wrap())
- if err != nil {
- panic(err)
- }
-}
-
-func (cn *conn) sendStartupPacket(m *writeBuf) {
- // sanity check
- if m.buf[0] != 0 {
- panic("oops")
- }
-
- _, err := cn.c.Write((m.wrap())[1:])
- if err != nil {
- panic(err)
- }
-}
-
-// Send a message of type typ to the server on the other end of cn. The
-// message should have no payload. This method does not use the scratch
-// buffer.
-func (cn *conn) sendSimpleMessage(typ byte) (err error) {
- _, err = cn.c.Write([]byte{typ, '\x00', '\x00', '\x00', '\x04'})
- return err
-}
-
-// saveMessage memorizes a message and its buffer in the conn struct.
-// recvMessage will then return these values on the next call to it. This
-// method is useful in cases where you have to see what the next message is
-// going to be (e.g. to see whether it's an error or not) but you can't handle
-// the message yourself.
-func (cn *conn) saveMessage(typ byte, buf *readBuf) {
- if cn.saveMessageType != 0 {
- cn.bad = true
- errorf("unexpected saveMessageType %d", cn.saveMessageType)
- }
- cn.saveMessageType = typ
- cn.saveMessageBuffer = *buf
-}
-
-// recvMessage receives any message from the backend, or returns an error if
-// a problem occurred while reading the message.
-func (cn *conn) recvMessage(r *readBuf) (byte, error) {
- // workaround for a QueryRow bug, see exec
- if cn.saveMessageType != 0 {
- t := cn.saveMessageType
- *r = cn.saveMessageBuffer
- cn.saveMessageType = 0
- cn.saveMessageBuffer = nil
- return t, nil
- }
-
- x := cn.scratch[:5]
- _, err := io.ReadFull(cn.buf, x)
- if err != nil {
- return 0, err
- }
-
- // read the type and length of the message that follows
- t := x[0]
- n := int(binary.BigEndian.Uint32(x[1:])) - 4
- var y []byte
- if n <= len(cn.scratch) {
- y = cn.scratch[:n]
- } else {
- y = make([]byte, n)
- }
- _, err = io.ReadFull(cn.buf, y)
- if err != nil {
- return 0, err
- }
- *r = y
- return t, nil
-}
-
-// recv receives a message from the backend, but if an error happened while
-// reading the message or the received message was an ErrorResponse, it panics.
-// NoticeResponses are ignored. This function should generally be used only
-// during the startup sequence.
-func (cn *conn) recv() (t byte, r *readBuf) {
- for {
- var err error
- r = &readBuf{}
- t, err = cn.recvMessage(r)
- if err != nil {
- panic(err)
- }
-
- switch t {
- case 'E':
- panic(parseError(r))
- case 'N':
- // ignore
- default:
- return
- }
- }
-}
-
-// recv1Buf is exactly equivalent to recv1, except it uses a buffer supplied by
-// the caller to avoid an allocation.
-func (cn *conn) recv1Buf(r *readBuf) byte {
- for {
- t, err := cn.recvMessage(r)
- if err != nil {
- panic(err)
- }
-
- switch t {
- case 'A', 'N':
- // ignore
- case 'S':
- cn.processParameterStatus(r)
- default:
- return t
- }
- }
-}
-
-// recv1 receives a message from the backend, panicking if an error occurs
-// while attempting to read it. All asynchronous messages are ignored, with
-// the exception of ErrorResponse.
-func (cn *conn) recv1() (t byte, r *readBuf) {
- r = &readBuf{}
- t = cn.recv1Buf(r)
- return t, r
-}
-
-func (cn *conn) ssl(o values) {
- verifyCaOnly := false
- tlsConf := tls.Config{}
- switch mode := o.Get("sslmode"); mode {
- case "require", "":
- tlsConf.InsecureSkipVerify = true
- case "verify-ca":
- // We must skip TLS's own verification since it requires full
- // verification since Go 1.3.
- tlsConf.InsecureSkipVerify = true
- verifyCaOnly = true
- case "verify-full":
- tlsConf.ServerName = o.Get("host")
- case "disable":
- return
- default:
- errorf(`unsupported sslmode %q; only "require" (default), "verify-full", and "disable" supported`, mode)
- }
-
- cn.setupSSLClientCertificates(&tlsConf, o)
- cn.setupSSLCA(&tlsConf, o)
-
- w := cn.writeBuf(0)
- w.int32(80877103)
- cn.sendStartupPacket(w)
-
- b := cn.scratch[:1]
- _, err := io.ReadFull(cn.c, b)
- if err != nil {
- panic(err)
- }
-
- if b[0] != 'S' {
- panic(ErrSSLNotSupported)
- }
-
- client := tls.Client(cn.c, &tlsConf)
- if verifyCaOnly {
- cn.verifyCA(client, &tlsConf)
- }
- cn.c = client
-}
-
-// verifyCA carries out a TLS handshake to the server and verifies the
-// presented certificate against the effective CA, i.e. the one specified in
-// sslrootcert or the system CA if sslrootcert was not specified.
-func (cn *conn) verifyCA(client *tls.Conn, tlsConf *tls.Config) {
- err := client.Handshake()
- if err != nil {
- panic(err)
- }
- certs := client.ConnectionState().PeerCertificates
- opts := x509.VerifyOptions{
- DNSName: client.ConnectionState().ServerName,
- Intermediates: x509.NewCertPool(),
- Roots: tlsConf.RootCAs,
- }
- for i, cert := range certs {
- if i == 0 {
- continue
- }
- opts.Intermediates.AddCert(cert)
- }
- _, err = certs[0].Verify(opts)
- if err != nil {
- panic(err)
- }
-}
-
-// This function sets up SSL client certificates based on either the "sslkey"
-// and "sslcert" settings (possibly set via the environment variables PGSSLKEY
-// and PGSSLCERT, respectively), or if they aren't set, from the .postgresql
-// directory in the user's home directory. If the file paths are set
-// explicitly, the files must exist. The key file must also not be
-// world-readable, or this function will panic with
-// ErrSSLKeyHasWorldPermissions.
-func (cn *conn) setupSSLClientCertificates(tlsConf *tls.Config, o values) {
- var missingOk bool
-
- sslkey := o.Get("sslkey")
- sslcert := o.Get("sslcert")
- if sslkey != "" && sslcert != "" {
- // If the user has set an sslkey and sslcert, they *must* exist.
- missingOk = false
- } else {
- // Automatically load certificates from ~/.postgresql.
- user, err := user.Current()
- if err != nil {
- // user.Current() might fail when cross-compiling. We have to
- // ignore the error and continue without client certificates, since
- // we wouldn't know where to load them from.
- return
- }
-
- sslkey = filepath.Join(user.HomeDir, ".postgresql", "postgresql.key")
- sslcert = filepath.Join(user.HomeDir, ".postgresql", "postgresql.crt")
- missingOk = true
- }
-
- // Check that both files exist, and report the error or stop, depending on
- // which behaviour we want. Note that we don't do any more extensive
- // checks than this (such as checking that the paths aren't directories);
- // LoadX509KeyPair() will take care of the rest.
- keyfinfo, err := os.Stat(sslkey)
- if err != nil && missingOk {
- return
- } else if err != nil {
- panic(err)
- }
- _, err = os.Stat(sslcert)
- if err != nil && missingOk {
- return
- } else if err != nil {
- panic(err)
- }
-
- // If we got this far, the key file must also have the correct permissions
- kmode := keyfinfo.Mode()
- if kmode != kmode&0600 {
- panic(ErrSSLKeyHasWorldPermissions)
- }
-
- cert, err := tls.LoadX509KeyPair(sslcert, sslkey)
- if err != nil {
- panic(err)
- }
- tlsConf.Certificates = []tls.Certificate{cert}
-}
-
-// Sets up RootCAs in the TLS configuration if sslrootcert is set.
-func (cn *conn) setupSSLCA(tlsConf *tls.Config, o values) {
- if sslrootcert := o.Get("sslrootcert"); sslrootcert != "" {
- tlsConf.RootCAs = x509.NewCertPool()
-
- cert, err := ioutil.ReadFile(sslrootcert)
- if err != nil {
- panic(err)
- }
-
- ok := tlsConf.RootCAs.AppendCertsFromPEM(cert)
- if !ok {
- errorf("couldn't parse pem in sslrootcert")
- }
- }
-}
-
-// isDriverSetting returns true iff a setting is purely for configuring the
-// driver's options and should not be sent to the server in the connection
-// startup packet.
-func isDriverSetting(key string) bool {
- switch key {
- case "host", "port":
- return true
- case "password":
- return true
- case "sslmode", "sslcert", "sslkey", "sslrootcert":
- return true
- case "fallback_application_name":
- return true
- case "connect_timeout":
- return true
- case "disable_prepared_binary_result":
- return true
- case "binary_parameters":
- return true
-
- default:
- return false
- }
-}
-
-func (cn *conn) startup(o values) {
- w := cn.writeBuf(0)
- w.int32(196608)
- // Send the backend the name of the database we want to connect to, and the
- // user we want to connect as. Additionally, we send over any run-time
- // parameters potentially included in the connection string. If the server
- // doesn't recognize any of them, it will reply with an error.
- for k, v := range o {
- if isDriverSetting(k) {
- // skip options which can't be run-time parameters
- continue
- }
- // The protocol requires us to supply the database name as "database"
- // instead of "dbname".
- if k == "dbname" {
- k = "database"
- }
- w.string(k)
- w.string(v)
- }
- w.string("")
- cn.sendStartupPacket(w)
-
- for {
- t, r := cn.recv()
- switch t {
- case 'K':
- case 'S':
- cn.processParameterStatus(r)
- case 'R':
- cn.auth(r, o)
- case 'Z':
- cn.processReadyForQuery(r)
- return
- default:
- errorf("unknown response for startup: %q", t)
- }
- }
-}
-
-func (cn *conn) auth(r *readBuf, o values) {
- switch code := r.int32(); code {
- case 0:
- // OK
- case 3:
- w := cn.writeBuf('p')
- w.string(o.Get("password"))
- cn.send(w)
-
- t, r := cn.recv()
- if t != 'R' {
- errorf("unexpected password response: %q", t)
- }
-
- if r.int32() != 0 {
- errorf("unexpected authentication response: %q", t)
- }
- case 5:
- s := string(r.next(4))
- w := cn.writeBuf('p')
- w.string("md5" + md5s(md5s(o.Get("password")+o.Get("user"))+s))
- cn.send(w)
-
- t, r := cn.recv()
- if t != 'R' {
- errorf("unexpected password response: %q", t)
- }
-
- if r.int32() != 0 {
- errorf("unexpected authentication response: %q", t)
- }
- default:
- errorf("unknown authentication response: %d", code)
- }
-}
-
-type format int
-
-const formatText format = 0
-const formatBinary format = 1
-
-// One result-column format code with the value 1 (i.e. all binary).
-var colFmtDataAllBinary []byte = []byte{0, 1, 0, 1}
-
-// No result-column format codes (i.e. all text).
-var colFmtDataAllText []byte = []byte{0, 0}
-
-type stmt struct {
- cn *conn
- name string
- colNames []string
- colFmts []format
- colFmtData []byte
- colTyps []oid.Oid
- paramTyps []oid.Oid
- closed bool
-}
-
-func (st *stmt) Close() (err error) {
- if st.closed {
- return nil
- }
- if st.cn.bad {
- return driver.ErrBadConn
- }
- defer st.cn.errRecover(&err)
-
- w := st.cn.writeBuf('C')
- w.byte('S')
- w.string(st.name)
- st.cn.send(w)
-
- st.cn.send(st.cn.writeBuf('S'))
-
- t, _ := st.cn.recv1()
- if t != '3' {
- st.cn.bad = true
- errorf("unexpected close response: %q", t)
- }
- st.closed = true
-
- t, r := st.cn.recv1()
- if t != 'Z' {
- st.cn.bad = true
- errorf("expected ready for query, but got: %q", t)
- }
- st.cn.processReadyForQuery(r)
-
- return nil
-}
-
-func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) {
- if st.cn.bad {
- return nil, driver.ErrBadConn
- }
- defer st.cn.errRecover(&err)
-
- st.exec(v)
- return &rows{
- cn: st.cn,
- colNames: st.colNames,
- colTyps: st.colTyps,
- colFmts: st.colFmts,
- }, nil
-}
-
-func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) {
- if st.cn.bad {
- return nil, driver.ErrBadConn
- }
- defer st.cn.errRecover(&err)
-
- st.exec(v)
- res, _, err = st.cn.readExecuteResponse("simple query")
- return res, err
-}
-
-func (st *stmt) exec(v []driver.Value) {
- if len(v) >= 65536 {
- errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(v))
- }
- if len(v) != len(st.paramTyps) {
- errorf("got %d parameters but the statement requires %d", len(v), len(st.paramTyps))
- }
-
- cn := st.cn
- w := cn.writeBuf('B')
- w.byte(0) // unnamed portal
- w.string(st.name)
-
- if cn.binaryParameters {
- cn.sendBinaryParameters(w, v)
- } else {
- w.int16(0)
- w.int16(len(v))
- for i, x := range v {
- if x == nil {
- w.int32(-1)
- } else {
- b := encode(&cn.parameterStatus, x, st.paramTyps[i])
- w.int32(len(b))
- w.bytes(b)
- }
- }
- }
- w.bytes(st.colFmtData)
-
- w.next('E')
- w.byte(0)
- w.int32(0)
-
- w.next('S')
- cn.send(w)
-
- cn.readBindResponse()
- cn.postExecuteWorkaround()
-
-}
-
-func (st *stmt) NumInput() int {
- return len(st.paramTyps)
-}
-
-// parseComplete parses the "command tag" from a CommandComplete message, and
-// returns the number of rows affected (if applicable) and a string
-// identifying only the command that was executed, e.g. "ALTER TABLE". If the
-// command tag could not be parsed, parseComplete panics.
-func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
- commandsWithAffectedRows := []string{
- "SELECT ",
- // INSERT is handled below
- "UPDATE ",
- "DELETE ",
- "FETCH ",
- "MOVE ",
- "COPY ",
- }
-
- var affectedRows *string
- for _, tag := range commandsWithAffectedRows {
- if strings.HasPrefix(commandTag, tag) {
- t := commandTag[len(tag):]
- affectedRows = &t
- commandTag = tag[:len(tag)-1]
- break
- }
- }
- // INSERT also includes the oid of the inserted row in its command tag.
- // Oids in user tables are deprecated, and the oid is only returned when
- // exactly one row is inserted, so it's unlikely to be of value to any
- // real-world application and we can ignore it.
- if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") {
- parts := strings.Split(commandTag, " ")
- if len(parts) != 3 {
- cn.bad = true
- errorf("unexpected INSERT command tag %s", commandTag)
- }
- affectedRows = &parts[len(parts)-1]
- commandTag = "INSERT"
- }
- // There should be no affected rows attached to the tag, just return it
- if affectedRows == nil {
- return driver.RowsAffected(0), commandTag
- }
- n, err := strconv.ParseInt(*affectedRows, 10, 64)
- if err != nil {
- cn.bad = true
- errorf("could not parse commandTag: %s", err)
- }
- return driver.RowsAffected(n), commandTag
-}
-
-type rows struct {
- cn *conn
- colNames []string
- colTyps []oid.Oid
- colFmts []format
- done bool
- rb readBuf
-}
-
-func (rs *rows) Close() error {
- // no need to look at cn.bad as Next() will
- for {
- err := rs.Next(nil)
- switch err {
- case nil:
- case io.EOF:
- return nil
- default:
- return err
- }
- }
-}
-
-func (rs *rows) Columns() []string {
- return rs.colNames
-}
-
-func (rs *rows) Next(dest []driver.Value) (err error) {
- if rs.done {
- return io.EOF
- }
-
- conn := rs.cn
- if conn.bad {
- return driver.ErrBadConn
- }
- defer conn.errRecover(&err)
-
- for {
- t := conn.recv1Buf(&rs.rb)
- switch t {
- case 'E':
- err = parseError(&rs.rb)
- case 'C', 'I':
- continue
- case 'Z':
- conn.processReadyForQuery(&rs.rb)
- rs.done = true
- if err != nil {
- return err
- }
- return io.EOF
- case 'D':
- n := rs.rb.int16()
- if err != nil {
- conn.bad = true
- errorf("unexpected DataRow after error %s", err)
- }
- if n < len(dest) {
- dest = dest[:n]
- }
- for i := range dest {
- l := rs.rb.int32()
- if l == -1 {
- dest[i] = nil
- continue
- }
- dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i], rs.colFmts[i])
- }
- return
- default:
- errorf("unexpected message after execute: %q", t)
- }
- }
-}
-
-// QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be
-// used as part of an SQL statement. For example:
-//
-// tblname := "my_table"
-// data := "my_data"
-// err = db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", pq.QuoteIdentifier(tblname)), data)
-//
-// Any double quotes in name will be escaped. The quoted identifier will be
-// case sensitive when used in a query. If the input string contains a zero
-// byte, the result will be truncated immediately before it.
-func QuoteIdentifier(name string) string {
- end := strings.IndexRune(name, 0)
- if end > -1 {
- name = name[:end]
- }
- return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
-}
-
-func md5s(s string) string {
- h := md5.New()
- h.Write([]byte(s))
- return fmt.Sprintf("%x", h.Sum(nil))
-}
-
-func (cn *conn) sendBinaryParameters(b *writeBuf, args []driver.Value) {
- // Do one pass over the parameters to see if we're going to send any of
- // them over in binary. If we are, create a paramFormats array at the
- // same time.
- var paramFormats []int
- for i, x := range args {
- _, ok := x.([]byte)
- if ok {
- if paramFormats == nil {
- paramFormats = make([]int, len(args))
- }
- paramFormats[i] = 1
- }
- }
- if paramFormats == nil {
- b.int16(0)
- } else {
- b.int16(len(paramFormats))
- for _, x := range paramFormats {
- b.int16(x)
- }
- }
-
- b.int16(len(args))
- for _, x := range args {
- if x == nil {
- b.int32(-1)
- } else {
- datum := binaryEncode(&cn.parameterStatus, x)
- b.int32(len(datum))
- b.bytes(datum)
- }
- }
-}
-
-func (cn *conn) sendBinaryModeQuery(query string, args []driver.Value) {
- if len(args) >= 65536 {
- errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(args))
- }
-
- b := cn.writeBuf('P')
- b.byte(0) // unnamed statement
- b.string(query)
- b.int16(0)
-
- b.next('B')
- b.int16(0) // unnamed portal and statement
- cn.sendBinaryParameters(b, args)
- b.bytes(colFmtDataAllText)
-
- b.next('D')
- b.byte('P')
- b.byte(0) // unnamed portal
-
- b.next('E')
- b.byte(0)
- b.int32(0)
-
- b.next('S')
- cn.send(b)
-}
-
-func (c *conn) processParameterStatus(r *readBuf) {
- var err error
-
- param := r.string()
- switch param {
- case "server_version":
- var major1 int
- var major2 int
- var minor int
- _, err = fmt.Sscanf(r.string(), "%d.%d.%d", &major1, &major2, &minor)
- if err == nil {
- c.parameterStatus.serverVersion = major1*10000 + major2*100 + minor
- }
-
- case "TimeZone":
- c.parameterStatus.currentLocation, err = time.LoadLocation(r.string())
- if err != nil {
- c.parameterStatus.currentLocation = nil
- }
-
- default:
- // ignore
- }
-}
-
-func (c *conn) processReadyForQuery(r *readBuf) {
- c.txnStatus = transactionStatus(r.byte())
-}
-
-func (cn *conn) readReadyForQuery() {
- t, r := cn.recv1()
- switch t {
- case 'Z':
- cn.processReadyForQuery(r)
- return
- default:
- cn.bad = true
- errorf("unexpected message %q; expected ReadyForQuery", t)
- }
-}
-
-func (cn *conn) readParseResponse() {
- t, r := cn.recv1()
- switch t {
- case '1':
- return
- case 'E':
- err := parseError(r)
- cn.readReadyForQuery()
- panic(err)
- default:
- cn.bad = true
- errorf("unexpected Parse response %q", t)
- }
-}
-
-func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []oid.Oid) {
- for {
- t, r := cn.recv1()
- switch t {
- case 't':
- nparams := r.int16()
- paramTyps = make([]oid.Oid, nparams)
- for i := range paramTyps {
- paramTyps[i] = r.oid()
- }
- case 'n':
- return paramTyps, nil, nil
- case 'T':
- colNames, colTyps = parseStatementRowDescribe(r)
- return paramTyps, colNames, colTyps
- case 'E':
- err := parseError(r)
- cn.readReadyForQuery()
- panic(err)
- default:
- cn.bad = true
- errorf("unexpected Describe statement response %q", t)
- }
- }
-}
-
-func (cn *conn) readPortalDescribeResponse() (colNames []string, colFmts []format, colTyps []oid.Oid) {
- t, r := cn.recv1()
- switch t {
- case 'T':
- return parsePortalRowDescribe(r)
- case 'n':
- return nil, nil, nil
- case 'E':
- err := parseError(r)
- cn.readReadyForQuery()
- panic(err)
- default:
- cn.bad = true
- errorf("unexpected Describe response %q", t)
- }
- panic("not reached")
-}
-
-func (cn *conn) readBindResponse() {
- t, r := cn.recv1()
- switch t {
- case '2':
- return
- case 'E':
- err := parseError(r)
- cn.readReadyForQuery()
- panic(err)
- default:
- cn.bad = true
- errorf("unexpected Bind response %q", t)
- }
-}
-
-func (cn *conn) postExecuteWorkaround() {
- // Work around a bug in sql.DB.QueryRow: in Go 1.2 and earlier it ignores
- // any errors from rows.Next, which masks errors that happened during the
- // execution of the query. To avoid the problem in common cases, we wait
- // here for one more message from the database. If it's not an error the
- // query will likely succeed (or perhaps has already, if it's a
- // CommandComplete), so we push the message into the conn struct; recv1
- // will return it as the next message for rows.Next or rows.Close.
- // However, if it's an error, we wait until ReadyForQuery and then return
- // the error to our caller.
- for {
- t, r := cn.recv1()
- switch t {
- case 'E':
- err := parseError(r)
- cn.readReadyForQuery()
- panic(err)
- case 'C', 'D', 'I':
- // the query didn't fail, but we can't process this message
- cn.saveMessage(t, r)
- return
- default:
- cn.bad = true
- errorf("unexpected message during extended query execution: %q", t)
- }
- }
-}
-
-// Only for Exec(), since we ignore the returned data
-func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, commandTag string, err error) {
- for {
- t, r := cn.recv1()
- switch t {
- case 'C':
- if err != nil {
- cn.bad = true
- errorf("unexpected CommandComplete after error %s", err)
- }
- res, commandTag = cn.parseComplete(r.string())
- case 'Z':
- cn.processReadyForQuery(r)
- return res, commandTag, err
- case 'E':
- err = parseError(r)
- case 'T', 'D', 'I':
- if err != nil {
- cn.bad = true
- errorf("unexpected %q after error %s", t, err)
- }
- // ignore any results
- default:
- cn.bad = true
- errorf("unknown %s response: %q", protocolState, t)
- }
- }
-}
-
-func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []oid.Oid) {
- n := r.int16()
- colNames = make([]string, n)
- colTyps = make([]oid.Oid, n)
- for i := range colNames {
- colNames[i] = r.string()
- r.next(6)
- colTyps[i] = r.oid()
- r.next(6)
- // format code not known when describing a statement; always 0
- r.next(2)
- }
- return
-}
-
-func parsePortalRowDescribe(r *readBuf) (colNames []string, colFmts []format, colTyps []oid.Oid) {
- n := r.int16()
- colNames = make([]string, n)
- colFmts = make([]format, n)
- colTyps = make([]oid.Oid, n)
- for i := range colNames {
- colNames[i] = r.string()
- r.next(6)
- colTyps[i] = r.oid()
- r.next(6)
- colFmts[i] = format(r.int16())
- }
- return
-}
-
-// parseEnviron tries to mimic some of libpq's environment handling
-//
-// To ease testing, it does not directly reference os.Environ, but is
-// designed to accept its output.
-//
-// Environment-set connection information is intended to have a higher
-// precedence than a library default but lower than any explicitly
-// passed information (such as in the URL or connection string).
-func parseEnviron(env []string) (out map[string]string) {
- out = make(map[string]string)
-
- for _, v := range env {
- parts := strings.SplitN(v, "=", 2)
-
- accrue := func(keyname string) {
- out[keyname] = parts[1]
- }
- unsupported := func() {
- panic(fmt.Sprintf("setting %v not supported", parts[0]))
- }
-
- // The order of these is the same as is seen in the
- // PostgreSQL 9.1 manual. Unsupported but well-defined
- // keys cause a panic; these should be unset prior to
- // execution. Options which pq expects to be set to a
- // certain value are allowed, but must be set to that
- // value if present (they can, of course, be absent).
- switch parts[0] {
- case "PGHOST":
- accrue("host")
- case "PGHOSTADDR":
- unsupported()
- case "PGPORT":
- accrue("port")
- case "PGDATABASE":
- accrue("dbname")
- case "PGUSER":
- accrue("user")
- case "PGPASSWORD":
- accrue("password")
- case "PGPASSFILE", "PGSERVICE", "PGSERVICEFILE", "PGREALM":
- unsupported()
- case "PGOPTIONS":
- accrue("options")
- case "PGAPPNAME":
- accrue("application_name")
- case "PGSSLMODE":
- accrue("sslmode")
- case "PGSSLCERT":
- accrue("sslcert")
- case "PGSSLKEY":
- accrue("sslkey")
- case "PGSSLROOTCERT":
- accrue("sslrootcert")
- case "PGREQUIRESSL", "PGSSLCRL":
- unsupported()
- case "PGREQUIREPEER":
- unsupported()
- case "PGKRBSRVNAME", "PGGSSLIB":
- unsupported()
- case "PGCONNECT_TIMEOUT":
- accrue("connect_timeout")
- case "PGCLIENTENCODING":
- accrue("client_encoding")
- case "PGDATESTYLE":
- accrue("datestyle")
- case "PGTZ":
- accrue("timezone")
- case "PGGEQO":
- accrue("geqo")
- case "PGSYSCONFDIR", "PGLOCALEDIR":
- unsupported()
- }
- }
-
- return out
-}
-
-// isUTF8 returns whether name is a fuzzy variation of the string "UTF-8".
-func isUTF8(name string) bool {
- // Recognize all sorts of silly things as "UTF-8", like Postgres does
- s := strings.Map(alnumLowerASCII, name)
- return s == "utf8" || s == "unicode"
-}
-
-func alnumLowerASCII(ch rune) rune {
- if 'A' <= ch && ch <= 'Z' {
- return ch + ('a' - 'A')
- }
- if 'a' <= ch && ch <= 'z' || '0' <= ch && ch <= '9' {
- return ch
- }
- return -1 // discard
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/copy.go b/Godeps/_workspace/src/github.com/lib/pq/copy.go
deleted file mode 100644
index 101f11133..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/copy.go
+++ /dev/null
@@ -1,267 +0,0 @@
-package pq
-
-import (
- "database/sql/driver"
- "encoding/binary"
- "errors"
- "fmt"
- "sync"
-)
-
-var (
- errCopyInClosed = errors.New("pq: copyin statement has already been closed")
- errBinaryCopyNotSupported = errors.New("pq: only text format supported for COPY")
- errCopyToNotSupported = errors.New("pq: COPY TO is not supported")
- errCopyNotSupportedOutsideTxn = errors.New("pq: COPY is only allowed inside a transaction")
-)
-
-// CopyIn creates a COPY FROM statement which can be prepared with
-// Tx.Prepare(). The target table should be visible in search_path.
-func CopyIn(table string, columns ...string) string {
- stmt := "COPY " + QuoteIdentifier(table) + " ("
- for i, col := range columns {
- if i != 0 {
- stmt += ", "
- }
- stmt += QuoteIdentifier(col)
- }
- stmt += ") FROM STDIN"
- return stmt
-}
-
-// CopyInSchema creates a COPY FROM statement which can be prepared with
-// Tx.Prepare().
-func CopyInSchema(schema, table string, columns ...string) string {
- stmt := "COPY " + QuoteIdentifier(schema) + "." + QuoteIdentifier(table) + " ("
- for i, col := range columns {
- if i != 0 {
- stmt += ", "
- }
- stmt += QuoteIdentifier(col)
- }
- stmt += ") FROM STDIN"
- return stmt
-}
-
-type copyin struct {
- cn *conn
- buffer []byte
- rowData chan []byte
- done chan bool
-
- closed bool
-
- sync.Mutex // guards err
- err error
-}
-
-const ciBufferSize = 64 * 1024
-
-// flush buffer before the buffer is filled up and needs reallocation
-const ciBufferFlushSize = 63 * 1024
-
-func (cn *conn) prepareCopyIn(q string) (_ driver.Stmt, err error) {
- if !cn.isInTransaction() {
- return nil, errCopyNotSupportedOutsideTxn
- }
-
- ci := &copyin{
- cn: cn,
- buffer: make([]byte, 0, ciBufferSize),
- rowData: make(chan []byte),
- done: make(chan bool, 1),
- }
- // add CopyData identifier + 4 bytes for message length
- ci.buffer = append(ci.buffer, 'd', 0, 0, 0, 0)
-
- b := cn.writeBuf('Q')
- b.string(q)
- cn.send(b)
-
-awaitCopyInResponse:
- for {
- t, r := cn.recv1()
- switch t {
- case 'G':
- if r.byte() != 0 {
- err = errBinaryCopyNotSupported
- break awaitCopyInResponse
- }
- go ci.resploop()
- return ci, nil
- case 'H':
- err = errCopyToNotSupported
- break awaitCopyInResponse
- case 'E':
- err = parseError(r)
- case 'Z':
- if err == nil {
- cn.bad = true
- errorf("unexpected ReadyForQuery in response to COPY")
- }
- cn.processReadyForQuery(r)
- return nil, err
- default:
- cn.bad = true
- errorf("unknown response for copy query: %q", t)
- }
- }
-
- // something went wrong, abort COPY before we return
- b = cn.writeBuf('f')
- b.string(err.Error())
- cn.send(b)
-
- for {
- t, r := cn.recv1()
- switch t {
- case 'c', 'C', 'E':
- case 'Z':
- // correctly aborted, we're done
- cn.processReadyForQuery(r)
- return nil, err
- default:
- cn.bad = true
- errorf("unknown response for CopyFail: %q", t)
- }
- }
-}
-
-func (ci *copyin) flush(buf []byte) {
- // set message length (without message identifier)
- binary.BigEndian.PutUint32(buf[1:], uint32(len(buf)-1))
-
- _, err := ci.cn.c.Write(buf)
- if err != nil {
- panic(err)
- }
-}
-
-func (ci *copyin) resploop() {
- for {
- var r readBuf
- t, err := ci.cn.recvMessage(&r)
- if err != nil {
- ci.cn.bad = true
- ci.setError(err)
- ci.done <- true
- return
- }
- switch t {
- case 'C':
- // complete
- case 'N':
- // NoticeResponse
- case 'Z':
- ci.cn.processReadyForQuery(&r)
- ci.done <- true
- return
- case 'E':
- err := parseError(&r)
- ci.setError(err)
- default:
- ci.cn.bad = true
- ci.setError(fmt.Errorf("unknown response during CopyIn: %q", t))
- ci.done <- true
- return
- }
- }
-}
-
-func (ci *copyin) isErrorSet() bool {
- ci.Lock()
- isSet := (ci.err != nil)
- ci.Unlock()
- return isSet
-}
-
-// setError() sets ci.err if one has not been set already. Caller must not be
-// holding ci.Mutex.
-func (ci *copyin) setError(err error) {
- ci.Lock()
- if ci.err == nil {
- ci.err = err
- }
- ci.Unlock()
-}
-
-func (ci *copyin) NumInput() int {
- return -1
-}
-
-func (ci *copyin) Query(v []driver.Value) (r driver.Rows, err error) {
- return nil, ErrNotSupported
-}
-
-// Exec inserts values into the COPY stream. The insert is asynchronous
-// and Exec can return errors from previous Exec calls to the same
-// COPY stmt.
-//
-// You need to call Exec(nil) to sync the COPY stream and to get any
-// errors from pending data, since Stmt.Close() doesn't return errors
-// to the user.
-func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
- if ci.closed {
- return nil, errCopyInClosed
- }
-
- if ci.cn.bad {
- return nil, driver.ErrBadConn
- }
- defer ci.cn.errRecover(&err)
-
- if ci.isErrorSet() {
- return nil, ci.err
- }
-
- if len(v) == 0 {
- return nil, ci.Close()
- }
-
- numValues := len(v)
- for i, value := range v {
- ci.buffer = appendEncodedText(&ci.cn.parameterStatus, ci.buffer, value)
- if i < numValues-1 {
- ci.buffer = append(ci.buffer, '\t')
- }
- }
-
- ci.buffer = append(ci.buffer, '\n')
-
- if len(ci.buffer) > ciBufferFlushSize {
- ci.flush(ci.buffer)
- // reset buffer, keep bytes for message identifier and length
- ci.buffer = ci.buffer[:5]
- }
-
- return driver.RowsAffected(0), nil
-}
-
-func (ci *copyin) Close() (err error) {
- if ci.closed { // Don't do anything, we're already closed
- return nil
- }
- ci.closed = true
-
- if ci.cn.bad {
- return driver.ErrBadConn
- }
- defer ci.cn.errRecover(&err)
-
- if len(ci.buffer) > 0 {
- ci.flush(ci.buffer)
- }
- // Avoid touching the scratch buffer as resploop could be using it.
- err = ci.cn.sendSimpleMessage('c')
- if err != nil {
- return err
- }
-
- <-ci.done
-
- if ci.isErrorSet() {
- err = ci.err
- return err
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/doc.go b/Godeps/_workspace/src/github.com/lib/pq/doc.go
deleted file mode 100644
index f772117d0..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/doc.go
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-Package pq is a pure Go Postgres driver for the database/sql package.
-
-In most cases clients will use the database/sql package instead of
-using this package directly. For example:
-
- import (
- "database/sql"
-
- _ "github.com/lib/pq"
- )
-
- func main() {
- db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
- if err != nil {
- log.Fatal(err)
- }
-
- age := 21
- rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
- …
- }
-
-You can also connect to a database using a URL. For example:
-
- db, err := sql.Open("postgres", "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full")
-
-
-Connection String Parameters
-
-
-Similarly to libpq, when establishing a connection using pq you are expected to
-supply a connection string containing zero or more parameters.
-A subset of the connection parameters supported by libpq are also supported by pq.
-Additionally, pq also lets you specify run-time parameters (such as search_path or work_mem)
-directly in the connection string. This is different from libpq, which does not allow
-run-time parameters in the connection string, instead requiring you to supply
-them in the options parameter.
-
-For compatibility with libpq, the following special connection parameters are
-supported:
-
- * dbname - The name of the database to connect to
- * user - The user to sign in as
- * password - The user's password
- * host - The host to connect to. Values that start with / are for unix domain sockets. (default is localhost)
- * port - The port to bind to. (default is 5432)
- * sslmode - Whether or not to use SSL (default is require, this is not the default for libpq)
- * fallback_application_name - An application_name to fall back to if one isn't provided.
- * connect_timeout - Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
- * sslcert - Cert file location. The file must contain PEM encoded data.
- * sslkey - Key file location. The file must contain PEM encoded data.
- * sslrootcert - The location of the root certificate file. The file must contain PEM encoded data.
-
-Valid values for sslmode are:
-
- * disable - No SSL
- * require - Always SSL (skip verification)
- * verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA)
- * verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate)
-
-See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
-for more information about connection string parameters.
-
-Use single quotes for values that contain whitespace:
-
- "user=pqgotest password='with spaces'"
-
-A backslash will escape the next character in values:
-
- "user=space\ man password='it\'s valid'
-
-Note that the connection parameter client_encoding (which sets the
-text encoding for the connection) may be set but must be "UTF8",
-matching with the same rules as Postgres. It is an error to provide
-any other value.
-
-In addition to the parameters listed above, any run-time parameter that can be
-set at backend start time can be set in the connection string. For more
-information, see
-http://www.postgresql.org/docs/current/static/runtime-config.html.
-
-Most environment variables as specified at http://www.postgresql.org/docs/current/static/libpq-envars.html
-supported by libpq are also supported by pq. If any of the environment
-variables not supported by pq are set, pq will panic during connection
-establishment. Environment variables have a lower precedence than explicitly
-provided connection parameters.
-
-
-Queries
-
-database/sql does not dictate any specific format for parameter
-markers in query strings, and pq uses the Postgres-native ordinal markers,
-as shown above. The same marker can be reused for the same parameter:
-
- rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1
- OR age BETWEEN $2 AND $2 + 3`, "orange", 64)
-
-pq does not support the LastInsertId() method of the Result type in database/sql.
-To return the identifier of an INSERT (or UPDATE or DELETE), use the Postgres
-RETURNING clause with a standard Query or QueryRow call:
-
- var userid int
- err := db.QueryRow(`INSERT INTO users(name, favorite_fruit, age)
- VALUES('beatrice', 'starfruit', 93) RETURNING id`).Scan(&userid)
-
-For more details on RETURNING, see the Postgres documentation:
-
- http://www.postgresql.org/docs/current/static/sql-insert.html
- http://www.postgresql.org/docs/current/static/sql-update.html
- http://www.postgresql.org/docs/current/static/sql-delete.html
-
-For additional instructions on querying see the documentation for the database/sql package.
-
-Errors
-
-pq may return errors of type *pq.Error which can be interrogated for error details:
-
- if err, ok := err.(*pq.Error); ok {
- fmt.Println("pq error:", err.Code.Name())
- }
-
-See the pq.Error type for details.
-
-
-Bulk imports
-
-You can perform bulk imports by preparing a statement returned by pq.CopyIn (or
-pq.CopyInSchema) in an explicit transaction (sql.Tx). The returned statement
-handle can then be repeatedly "executed" to copy data into the target table.
-After all data has been processed you should call Exec() once with no arguments
-to flush all buffered data. Any call to Exec() might return an error which
-should be handled appropriately, but because of the internal buffering an error
-returned by Exec() might not be related to the data passed in the call that
-failed.
-
-CopyIn uses COPY FROM internally. It is not possible to COPY outside of an
-explicit transaction in pq.
-
-Usage example:
-
- txn, err := db.Begin()
- if err != nil {
- log.Fatal(err)
- }
-
- stmt, err := txn.Prepare(pq.CopyIn("users", "name", "age"))
- if err != nil {
- log.Fatal(err)
- }
-
- for _, user := range users {
- _, err = stmt.Exec(user.Name, int64(user.Age))
- if err != nil {
- log.Fatal(err)
- }
- }
-
- _, err = stmt.Exec()
- if err != nil {
- log.Fatal(err)
- }
-
- err = stmt.Close()
- if err != nil {
- log.Fatal(err)
- }
-
- err = txn.Commit()
- if err != nil {
- log.Fatal(err)
- }
-
-
-Notifications
-
-
-PostgreSQL supports a simple publish/subscribe model over database
-connections. See http://www.postgresql.org/docs/current/static/sql-notify.html
-for more information about the general mechanism.
-
-To start listening for notifications, you first have to open a new connection
-to the database by calling NewListener. This connection can not be used for
-anything other than LISTEN / NOTIFY. Calling Listen will open a "notification
-channel"; once a notification channel is open, a notification generated on that
-channel will effect a send on the Listener.Notify channel. A notification
-channel will remain open until Unlisten is called, though connection loss might
-result in some notifications being lost. To solve this problem, Listener sends
-a nil pointer over the Notify channel any time the connection is re-established
-following a connection loss. The application can get information about the
-state of the underlying connection by setting an event callback in the call to
-NewListener.
-
-A single Listener can safely be used from concurrent goroutines, which means
-that there is often no need to create more than one Listener in your
-application. However, a Listener is always connected to a single database, so
-you will need to create a new Listener instance for every database you want to
-receive notifications in.
-
-The channel name in both Listen and Unlisten is case sensitive, and can contain
-any characters legal in an identifier (see
-http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
-for more information). Note that the channel name will be truncated to 63
-bytes by the PostgreSQL server.
-
-You can find a complete, working example of Listener usage at
-http://godoc.org/github.com/lib/pq/listen_example.
-
-*/
-package pq
diff --git a/Godeps/_workspace/src/github.com/lib/pq/encode.go b/Godeps/_workspace/src/github.com/lib/pq/encode.go
deleted file mode 100644
index 88422eb3d..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/encode.go
+++ /dev/null
@@ -1,538 +0,0 @@
-package pq
-
-import (
- "bytes"
- "database/sql/driver"
- "encoding/binary"
- "encoding/hex"
- "fmt"
- "math"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "github.com/lib/pq/oid"
-)
-
-func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte {
- switch v := x.(type) {
- case []byte:
- return v
- default:
- return encode(parameterStatus, x, oid.T_unknown)
- }
- panic("not reached")
-}
-
-func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) []byte {
- switch v := x.(type) {
- case int64:
- return strconv.AppendInt(nil, v, 10)
- case float64:
- return strconv.AppendFloat(nil, v, 'f', -1, 64)
- case []byte:
- if pgtypOid == oid.T_bytea {
- return encodeBytea(parameterStatus.serverVersion, v)
- }
-
- return v
- case string:
- if pgtypOid == oid.T_bytea {
- return encodeBytea(parameterStatus.serverVersion, []byte(v))
- }
-
- return []byte(v)
- case bool:
- return strconv.AppendBool(nil, v)
- case time.Time:
- return formatTs(v)
-
- default:
- errorf("encode: unknown type for %T", v)
- }
-
- panic("not reached")
-}
-
-func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid, f format) interface{} {
- if f == formatBinary {
- return binaryDecode(parameterStatus, s, typ)
- } else {
- return textDecode(parameterStatus, s, typ)
- }
-}
-
-func binaryDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} {
- switch typ {
- case oid.T_bytea:
- return s
- case oid.T_int8:
- return int64(binary.BigEndian.Uint64(s))
- case oid.T_int4:
- return int64(int32(binary.BigEndian.Uint32(s)))
- case oid.T_int2:
- return int64(int16(binary.BigEndian.Uint16(s)))
-
- default:
- errorf("don't know how to decode binary parameter of type %u", uint32(typ))
- }
-
- panic("not reached")
-}
-
-func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} {
- switch typ {
- case oid.T_bytea:
- return parseBytea(s)
- case oid.T_timestamptz:
- return parseTs(parameterStatus.currentLocation, string(s))
- case oid.T_timestamp, oid.T_date:
- return parseTs(nil, string(s))
- case oid.T_time:
- return mustParse("15:04:05", typ, s)
- case oid.T_timetz:
- return mustParse("15:04:05-07", typ, s)
- case oid.T_bool:
- return s[0] == 't'
- case oid.T_int8, oid.T_int4, oid.T_int2:
- i, err := strconv.ParseInt(string(s), 10, 64)
- if err != nil {
- errorf("%s", err)
- }
- return i
- case oid.T_float4, oid.T_float8:
- bits := 64
- if typ == oid.T_float4 {
- bits = 32
- }
- f, err := strconv.ParseFloat(string(s), bits)
- if err != nil {
- errorf("%s", err)
- }
- return f
- }
-
- return s
-}
-
-// appendEncodedText encodes item in text format as required by COPY
-// and appends to buf
-func appendEncodedText(parameterStatus *parameterStatus, buf []byte, x interface{}) []byte {
- switch v := x.(type) {
- case int64:
- return strconv.AppendInt(buf, v, 10)
- case float64:
- return strconv.AppendFloat(buf, v, 'f', -1, 64)
- case []byte:
- encodedBytea := encodeBytea(parameterStatus.serverVersion, v)
- return appendEscapedText(buf, string(encodedBytea))
- case string:
- return appendEscapedText(buf, v)
- case bool:
- return strconv.AppendBool(buf, v)
- case time.Time:
- return append(buf, formatTs(v)...)
- case nil:
- return append(buf, "\\N"...)
- default:
- errorf("encode: unknown type for %T", v)
- }
-
- panic("not reached")
-}
-
-func appendEscapedText(buf []byte, text string) []byte {
- escapeNeeded := false
- startPos := 0
- var c byte
-
- // check if we need to escape
- for i := 0; i < len(text); i++ {
- c = text[i]
- if c == '\\' || c == '\n' || c == '\r' || c == '\t' {
- escapeNeeded = true
- startPos = i
- break
- }
- }
- if !escapeNeeded {
- return append(buf, text...)
- }
-
- // copy till first char to escape, iterate the rest
- result := append(buf, text[:startPos]...)
- for i := startPos; i < len(text); i++ {
- c = text[i]
- switch c {
- case '\\':
- result = append(result, '\\', '\\')
- case '\n':
- result = append(result, '\\', 'n')
- case '\r':
- result = append(result, '\\', 'r')
- case '\t':
- result = append(result, '\\', 't')
- default:
- result = append(result, c)
- }
- }
- return result
-}
-
-func mustParse(f string, typ oid.Oid, s []byte) time.Time {
- str := string(s)
-
- // check for a 30-minute-offset timezone
- if (typ == oid.T_timestamptz || typ == oid.T_timetz) &&
- str[len(str)-3] == ':' {
- f += ":00"
- }
- t, err := time.Parse(f, str)
- if err != nil {
- errorf("decode: %s", err)
- }
- return t
-}
-
-func expect(str, char string, pos int) {
- if c := str[pos : pos+1]; c != char {
- errorf("expected '%v' at position %v; got '%v'", char, pos, c)
- }
-}
-
-func mustAtoi(str string) int {
- result, err := strconv.Atoi(str)
- if err != nil {
- errorf("expected number; got '%v'", str)
- }
- return result
-}
-
-// The location cache caches the time zones typically used by the client.
-type locationCache struct {
- cache map[int]*time.Location
- lock sync.Mutex
-}
-
-// All connections share the same list of timezones. Benchmarking shows that
-// about 5% speed could be gained by putting the cache in the connection and
-// losing the mutex, at the cost of a small amount of memory and a somewhat
-// significant increase in code complexity.
-var globalLocationCache *locationCache = newLocationCache()
-
-func newLocationCache() *locationCache {
- return &locationCache{cache: make(map[int]*time.Location)}
-}
-
-// Returns the cached timezone for the specified offset, creating and caching
-// it if necessary.
-func (c *locationCache) getLocation(offset int) *time.Location {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- location, ok := c.cache[offset]
- if !ok {
- location = time.FixedZone("", offset)
- c.cache[offset] = location
- }
-
- return location
-}
-
-var infinityTsEnabled = false
-var infinityTsNegative time.Time
-var infinityTsPositive time.Time
-
-const (
- infinityTsEnabledAlready = "pq: infinity timestamp enabled already"
- infinityTsNegativeMustBeSmaller = "pq: infinity timestamp: negative value must be smaller (before) than positive"
-)
-
-/*
- * If EnableInfinityTs is not called, "-infinity" and "infinity" will return
- * []byte("-infinity") and []byte("infinity") respectively, and potentially
- * cause error "sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time",
- * when scanning into a time.Time value.
- *
- * Once EnableInfinityTs has been called, all connections created using this
- * driver will decode Postgres' "-infinity" and "infinity" for "timestamp",
- * "timestamp with time zone" and "date" types to the predefined minimum and
- * maximum times, respectively. When encoding time.Time values, any time which
- * equals or preceeds the predefined minimum time will be encoded to
- * "-infinity". Any values at or past the maximum time will similarly be
- * encoded to "infinity".
- *
- *
- * If EnableInfinityTs is called with negative >= positive, it will panic.
- * Calling EnableInfinityTs after a connection has been established results in
- * undefined behavior. If EnableInfinityTs is called more than once, it will
- * panic.
- */
-func EnableInfinityTs(negative time.Time, positive time.Time) {
- if infinityTsEnabled {
- panic(infinityTsEnabledAlready)
- }
- if !negative.Before(positive) {
- panic(infinityTsNegativeMustBeSmaller)
- }
- infinityTsEnabled = true
- infinityTsNegative = negative
- infinityTsPositive = positive
-}
-
-/*
- * Testing might want to toggle infinityTsEnabled
- */
-func disableInfinityTs() {
- infinityTsEnabled = false
-}
-
-// This is a time function specific to the Postgres default DateStyle
-// setting ("ISO, MDY"), the only one we currently support. This
-// accounts for the discrepancies between the parsing available with
-// time.Parse and the Postgres date formatting quirks.
-func parseTs(currentLocation *time.Location, str string) interface{} {
- switch str {
- case "-infinity":
- if infinityTsEnabled {
- return infinityTsNegative
- }
- return []byte(str)
- case "infinity":
- if infinityTsEnabled {
- return infinityTsPositive
- }
- return []byte(str)
- }
-
- monSep := strings.IndexRune(str, '-')
- // this is Gregorian year, not ISO Year
- // In Gregorian system, the year 1 BC is followed by AD 1
- year := mustAtoi(str[:monSep])
- daySep := monSep + 3
- month := mustAtoi(str[monSep+1 : daySep])
- expect(str, "-", daySep)
- timeSep := daySep + 3
- day := mustAtoi(str[daySep+1 : timeSep])
-
- var hour, minute, second int
- if len(str) > monSep+len("01-01")+1 {
- expect(str, " ", timeSep)
- minSep := timeSep + 3
- expect(str, ":", minSep)
- hour = mustAtoi(str[timeSep+1 : minSep])
- secSep := minSep + 3
- expect(str, ":", secSep)
- minute = mustAtoi(str[minSep+1 : secSep])
- secEnd := secSep + 3
- second = mustAtoi(str[secSep+1 : secEnd])
- }
- remainderIdx := monSep + len("01-01 00:00:00") + 1
- // Three optional (but ordered) sections follow: the
- // fractional seconds, the time zone offset, and the BC
- // designation. We set them up here and adjust the other
- // offsets if the preceding sections exist.
-
- nanoSec := 0
- tzOff := 0
-
- if remainderIdx < len(str) && str[remainderIdx:remainderIdx+1] == "." {
- fracStart := remainderIdx + 1
- fracOff := strings.IndexAny(str[fracStart:], "-+ ")
- if fracOff < 0 {
- fracOff = len(str) - fracStart
- }
- fracSec := mustAtoi(str[fracStart : fracStart+fracOff])
- nanoSec = fracSec * (1000000000 / int(math.Pow(10, float64(fracOff))))
-
- remainderIdx += fracOff + 1
- }
- if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart:tzStart+1] == "-" || str[tzStart:tzStart+1] == "+") {
- // time zone separator is always '-' or '+' (UTC is +00)
- var tzSign int
- if c := str[tzStart : tzStart+1]; c == "-" {
- tzSign = -1
- } else if c == "+" {
- tzSign = +1
- } else {
- errorf("expected '-' or '+' at position %v; got %v", tzStart, c)
- }
- tzHours := mustAtoi(str[tzStart+1 : tzStart+3])
- remainderIdx += 3
- var tzMin, tzSec int
- if tzStart+3 < len(str) && str[tzStart+3:tzStart+4] == ":" {
- tzMin = mustAtoi(str[tzStart+4 : tzStart+6])
- remainderIdx += 3
- }
- if tzStart+6 < len(str) && str[tzStart+6:tzStart+7] == ":" {
- tzSec = mustAtoi(str[tzStart+7 : tzStart+9])
- remainderIdx += 3
- }
- tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
- }
- var isoYear int
- if remainderIdx < len(str) && str[remainderIdx:remainderIdx+3] == " BC" {
- isoYear = 1 - year
- remainderIdx += 3
- } else {
- isoYear = year
- }
- if remainderIdx < len(str) {
- errorf("expected end of input, got %v", str[remainderIdx:])
- }
- t := time.Date(isoYear, time.Month(month), day,
- hour, minute, second, nanoSec,
- globalLocationCache.getLocation(tzOff))
-
- if currentLocation != nil {
- // Set the location of the returned Time based on the session's
- // TimeZone value, but only if the local time zone database agrees with
- // the remote database on the offset.
- lt := t.In(currentLocation)
- _, newOff := lt.Zone()
- if newOff == tzOff {
- t = lt
- }
- }
-
- return t
-}
-
-// formatTs formats t into a format postgres understands.
-func formatTs(t time.Time) (b []byte) {
- if infinityTsEnabled {
- // t <= -infinity : ! (t > -infinity)
- if !t.After(infinityTsNegative) {
- return []byte("-infinity")
- }
- // t >= infinity : ! (!t < infinity)
- if !t.Before(infinityTsPositive) {
- return []byte("infinity")
- }
- }
- // Need to send dates before 0001 A.D. with " BC" suffix, instead of the
- // minus sign preferred by Go.
- // Beware, "0000" in ISO is "1 BC", "-0001" is "2 BC" and so on
- bc := false
- if t.Year() <= 0 {
- // flip year sign, and add 1, e.g: "0" will be "1", and "-10" will be "11"
- t = t.AddDate((-t.Year())*2+1, 0, 0)
- bc = true
- }
- b = []byte(t.Format(time.RFC3339Nano))
-
- _, offset := t.Zone()
- offset = offset % 60
- if offset != 0 {
- // RFC3339Nano already printed the minus sign
- if offset < 0 {
- offset = -offset
- }
-
- b = append(b, ':')
- if offset < 10 {
- b = append(b, '0')
- }
- b = strconv.AppendInt(b, int64(offset), 10)
- }
-
- if bc {
- b = append(b, " BC"...)
- }
- return b
-}
-
-// Parse a bytea value received from the server. Both "hex" and the legacy
-// "escape" format are supported.
-func parseBytea(s []byte) (result []byte) {
- if len(s) >= 2 && bytes.Equal(s[:2], []byte("\\x")) {
- // bytea_output = hex
- s = s[2:] // trim off leading "\\x"
- result = make([]byte, hex.DecodedLen(len(s)))
- _, err := hex.Decode(result, s)
- if err != nil {
- errorf("%s", err)
- }
- } else {
- // bytea_output = escape
- for len(s) > 0 {
- if s[0] == '\\' {
- // escaped '\\'
- if len(s) >= 2 && s[1] == '\\' {
- result = append(result, '\\')
- s = s[2:]
- continue
- }
-
- // '\\' followed by an octal number
- if len(s) < 4 {
- errorf("invalid bytea sequence %v", s)
- }
- r, err := strconv.ParseInt(string(s[1:4]), 8, 9)
- if err != nil {
- errorf("could not parse bytea value: %s", err.Error())
- }
- result = append(result, byte(r))
- s = s[4:]
- } else {
- // We hit an unescaped, raw byte. Try to read in as many as
- // possible in one go.
- i := bytes.IndexByte(s, '\\')
- if i == -1 {
- result = append(result, s...)
- break
- }
- result = append(result, s[:i]...)
- s = s[i:]
- }
- }
- }
-
- return result
-}
-
-func encodeBytea(serverVersion int, v []byte) (result []byte) {
- if serverVersion >= 90000 {
- // Use the hex format if we know that the server supports it
- result = make([]byte, 2+hex.EncodedLen(len(v)))
- result[0] = '\\'
- result[1] = 'x'
- hex.Encode(result[2:], v)
- } else {
- // .. or resort to "escape"
- for _, b := range v {
- if b == '\\' {
- result = append(result, '\\', '\\')
- } else if b < 0x20 || b > 0x7e {
- result = append(result, []byte(fmt.Sprintf("\\%03o", b))...)
- } else {
- result = append(result, b)
- }
- }
- }
-
- return result
-}
-
-// NullTime represents a time.Time that may be null. NullTime implements the
-// sql.Scanner interface so it can be used as a scan destination, similar to
-// sql.NullString.
-type NullTime struct {
- Time time.Time
- Valid bool // Valid is true if Time is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (nt *NullTime) Scan(value interface{}) error {
- nt.Time, nt.Valid = value.(time.Time)
- return nil
-}
-
-// Value implements the driver Valuer interface.
-func (nt NullTime) Value() (driver.Value, error) {
- if !nt.Valid {
- return nil, nil
- }
- return nt.Time, nil
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/error.go b/Godeps/_workspace/src/github.com/lib/pq/error.go
deleted file mode 100644
index b4bb44cee..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/error.go
+++ /dev/null
@@ -1,508 +0,0 @@
-package pq
-
-import (
- "database/sql/driver"
- "fmt"
- "io"
- "net"
- "runtime"
-)
-
-// Error severities
-const (
- Efatal = "FATAL"
- Epanic = "PANIC"
- Ewarning = "WARNING"
- Enotice = "NOTICE"
- Edebug = "DEBUG"
- Einfo = "INFO"
- Elog = "LOG"
-)
-
-// Error represents an error communicating with the server.
-//
-// See http://www.postgresql.org/docs/current/static/protocol-error-fields.html for details of the fields
-type Error struct {
- Severity string
- Code ErrorCode
- Message string
- Detail string
- Hint string
- Position string
- InternalPosition string
- InternalQuery string
- Where string
- Schema string
- Table string
- Column string
- DataTypeName string
- Constraint string
- File string
- Line string
- Routine string
-}
-
-// ErrorCode is a five-character error code.
-type ErrorCode string
-
-// Name returns a more human friendly rendering of the error code, namely the
-// "condition name".
-//
-// See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for
-// details.
-func (ec ErrorCode) Name() string {
- return errorCodeNames[ec]
-}
-
-// ErrorClass is only the class part of an error code.
-type ErrorClass string
-
-// Name returns the condition name of an error class. It is equivalent to the
-// condition name of the "standard" error code (i.e. the one having the last
-// three characters "000").
-func (ec ErrorClass) Name() string {
- return errorCodeNames[ErrorCode(ec+"000")]
-}
-
-// Class returns the error class, e.g. "28".
-//
-// See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for
-// details.
-func (ec ErrorCode) Class() ErrorClass {
- return ErrorClass(ec[0:2])
-}
-
-// errorCodeNames is a mapping between the five-character error codes and the
-// human readable "condition names". It is derived from the list at
-// http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
-var errorCodeNames = map[ErrorCode]string{
- // Class 00 - Successful Completion
- "00000": "successful_completion",
- // Class 01 - Warning
- "01000": "warning",
- "0100C": "dynamic_result_sets_returned",
- "01008": "implicit_zero_bit_padding",
- "01003": "null_value_eliminated_in_set_function",
- "01007": "privilege_not_granted",
- "01006": "privilege_not_revoked",
- "01004": "string_data_right_truncation",
- "01P01": "deprecated_feature",
- // Class 02 - No Data (this is also a warning class per the SQL standard)
- "02000": "no_data",
- "02001": "no_additional_dynamic_result_sets_returned",
- // Class 03 - SQL Statement Not Yet Complete
- "03000": "sql_statement_not_yet_complete",
- // Class 08 - Connection Exception
- "08000": "connection_exception",
- "08003": "connection_does_not_exist",
- "08006": "connection_failure",
- "08001": "sqlclient_unable_to_establish_sqlconnection",
- "08004": "sqlserver_rejected_establishment_of_sqlconnection",
- "08007": "transaction_resolution_unknown",
- "08P01": "protocol_violation",
- // Class 09 - Triggered Action Exception
- "09000": "triggered_action_exception",
- // Class 0A - Feature Not Supported
- "0A000": "feature_not_supported",
- // Class 0B - Invalid Transaction Initiation
- "0B000": "invalid_transaction_initiation",
- // Class 0F - Locator Exception
- "0F000": "locator_exception",
- "0F001": "invalid_locator_specification",
- // Class 0L - Invalid Grantor
- "0L000": "invalid_grantor",
- "0LP01": "invalid_grant_operation",
- // Class 0P - Invalid Role Specification
- "0P000": "invalid_role_specification",
- // Class 0Z - Diagnostics Exception
- "0Z000": "diagnostics_exception",
- "0Z002": "stacked_diagnostics_accessed_without_active_handler",
- // Class 20 - Case Not Found
- "20000": "case_not_found",
- // Class 21 - Cardinality Violation
- "21000": "cardinality_violation",
- // Class 22 - Data Exception
- "22000": "data_exception",
- "2202E": "array_subscript_error",
- "22021": "character_not_in_repertoire",
- "22008": "datetime_field_overflow",
- "22012": "division_by_zero",
- "22005": "error_in_assignment",
- "2200B": "escape_character_conflict",
- "22022": "indicator_overflow",
- "22015": "interval_field_overflow",
- "2201E": "invalid_argument_for_logarithm",
- "22014": "invalid_argument_for_ntile_function",
- "22016": "invalid_argument_for_nth_value_function",
- "2201F": "invalid_argument_for_power_function",
- "2201G": "invalid_argument_for_width_bucket_function",
- "22018": "invalid_character_value_for_cast",
- "22007": "invalid_datetime_format",
- "22019": "invalid_escape_character",
- "2200D": "invalid_escape_octet",
- "22025": "invalid_escape_sequence",
- "22P06": "nonstandard_use_of_escape_character",
- "22010": "invalid_indicator_parameter_value",
- "22023": "invalid_parameter_value",
- "2201B": "invalid_regular_expression",
- "2201W": "invalid_row_count_in_limit_clause",
- "2201X": "invalid_row_count_in_result_offset_clause",
- "22009": "invalid_time_zone_displacement_value",
- "2200C": "invalid_use_of_escape_character",
- "2200G": "most_specific_type_mismatch",
- "22004": "null_value_not_allowed",
- "22002": "null_value_no_indicator_parameter",
- "22003": "numeric_value_out_of_range",
- "22026": "string_data_length_mismatch",
- "22001": "string_data_right_truncation",
- "22011": "substring_error",
- "22027": "trim_error",
- "22024": "unterminated_c_string",
- "2200F": "zero_length_character_string",
- "22P01": "floating_point_exception",
- "22P02": "invalid_text_representation",
- "22P03": "invalid_binary_representation",
- "22P04": "bad_copy_file_format",
- "22P05": "untranslatable_character",
- "2200L": "not_an_xml_document",
- "2200M": "invalid_xml_document",
- "2200N": "invalid_xml_content",
- "2200S": "invalid_xml_comment",
- "2200T": "invalid_xml_processing_instruction",
- // Class 23 - Integrity Constraint Violation
- "23000": "integrity_constraint_violation",
- "23001": "restrict_violation",
- "23502": "not_null_violation",
- "23503": "foreign_key_violation",
- "23505": "unique_violation",
- "23514": "check_violation",
- "23P01": "exclusion_violation",
- // Class 24 - Invalid Cursor State
- "24000": "invalid_cursor_state",
- // Class 25 - Invalid Transaction State
- "25000": "invalid_transaction_state",
- "25001": "active_sql_transaction",
- "25002": "branch_transaction_already_active",
- "25008": "held_cursor_requires_same_isolation_level",
- "25003": "inappropriate_access_mode_for_branch_transaction",
- "25004": "inappropriate_isolation_level_for_branch_transaction",
- "25005": "no_active_sql_transaction_for_branch_transaction",
- "25006": "read_only_sql_transaction",
- "25007": "schema_and_data_statement_mixing_not_supported",
- "25P01": "no_active_sql_transaction",
- "25P02": "in_failed_sql_transaction",
- // Class 26 - Invalid SQL Statement Name
- "26000": "invalid_sql_statement_name",
- // Class 27 - Triggered Data Change Violation
- "27000": "triggered_data_change_violation",
- // Class 28 - Invalid Authorization Specification
- "28000": "invalid_authorization_specification",
- "28P01": "invalid_password",
- // Class 2B - Dependent Privilege Descriptors Still Exist
- "2B000": "dependent_privilege_descriptors_still_exist",
- "2BP01": "dependent_objects_still_exist",
- // Class 2D - Invalid Transaction Termination
- "2D000": "invalid_transaction_termination",
- // Class 2F - SQL Routine Exception
- "2F000": "sql_routine_exception",
- "2F005": "function_executed_no_return_statement",
- "2F002": "modifying_sql_data_not_permitted",
- "2F003": "prohibited_sql_statement_attempted",
- "2F004": "reading_sql_data_not_permitted",
- // Class 34 - Invalid Cursor Name
- "34000": "invalid_cursor_name",
- // Class 38 - External Routine Exception
- "38000": "external_routine_exception",
- "38001": "containing_sql_not_permitted",
- "38002": "modifying_sql_data_not_permitted",
- "38003": "prohibited_sql_statement_attempted",
- "38004": "reading_sql_data_not_permitted",
- // Class 39 - External Routine Invocation Exception
- "39000": "external_routine_invocation_exception",
- "39001": "invalid_sqlstate_returned",
- "39004": "null_value_not_allowed",
- "39P01": "trigger_protocol_violated",
- "39P02": "srf_protocol_violated",
- // Class 3B - Savepoint Exception
- "3B000": "savepoint_exception",
- "3B001": "invalid_savepoint_specification",
- // Class 3D - Invalid Catalog Name
- "3D000": "invalid_catalog_name",
- // Class 3F - Invalid Schema Name
- "3F000": "invalid_schema_name",
- // Class 40 - Transaction Rollback
- "40000": "transaction_rollback",
- "40002": "transaction_integrity_constraint_violation",
- "40001": "serialization_failure",
- "40003": "statement_completion_unknown",
- "40P01": "deadlock_detected",
- // Class 42 - Syntax Error or Access Rule Violation
- "42000": "syntax_error_or_access_rule_violation",
- "42601": "syntax_error",
- "42501": "insufficient_privilege",
- "42846": "cannot_coerce",
- "42803": "grouping_error",
- "42P20": "windowing_error",
- "42P19": "invalid_recursion",
- "42830": "invalid_foreign_key",
- "42602": "invalid_name",
- "42622": "name_too_long",
- "42939": "reserved_name",
- "42804": "datatype_mismatch",
- "42P18": "indeterminate_datatype",
- "42P21": "collation_mismatch",
- "42P22": "indeterminate_collation",
- "42809": "wrong_object_type",
- "42703": "undefined_column",
- "42883": "undefined_function",
- "42P01": "undefined_table",
- "42P02": "undefined_parameter",
- "42704": "undefined_object",
- "42701": "duplicate_column",
- "42P03": "duplicate_cursor",
- "42P04": "duplicate_database",
- "42723": "duplicate_function",
- "42P05": "duplicate_prepared_statement",
- "42P06": "duplicate_schema",
- "42P07": "duplicate_table",
- "42712": "duplicate_alias",
- "42710": "duplicate_object",
- "42702": "ambiguous_column",
- "42725": "ambiguous_function",
- "42P08": "ambiguous_parameter",
- "42P09": "ambiguous_alias",
- "42P10": "invalid_column_reference",
- "42611": "invalid_column_definition",
- "42P11": "invalid_cursor_definition",
- "42P12": "invalid_database_definition",
- "42P13": "invalid_function_definition",
- "42P14": "invalid_prepared_statement_definition",
- "42P15": "invalid_schema_definition",
- "42P16": "invalid_table_definition",
- "42P17": "invalid_object_definition",
- // Class 44 - WITH CHECK OPTION Violation
- "44000": "with_check_option_violation",
- // Class 53 - Insufficient Resources
- "53000": "insufficient_resources",
- "53100": "disk_full",
- "53200": "out_of_memory",
- "53300": "too_many_connections",
- "53400": "configuration_limit_exceeded",
- // Class 54 - Program Limit Exceeded
- "54000": "program_limit_exceeded",
- "54001": "statement_too_complex",
- "54011": "too_many_columns",
- "54023": "too_many_arguments",
- // Class 55 - Object Not In Prerequisite State
- "55000": "object_not_in_prerequisite_state",
- "55006": "object_in_use",
- "55P02": "cant_change_runtime_param",
- "55P03": "lock_not_available",
- // Class 57 - Operator Intervention
- "57000": "operator_intervention",
- "57014": "query_canceled",
- "57P01": "admin_shutdown",
- "57P02": "crash_shutdown",
- "57P03": "cannot_connect_now",
- "57P04": "database_dropped",
- // Class 58 - System Error (errors external to PostgreSQL itself)
- "58000": "system_error",
- "58030": "io_error",
- "58P01": "undefined_file",
- "58P02": "duplicate_file",
- // Class F0 - Configuration File Error
- "F0000": "config_file_error",
- "F0001": "lock_file_exists",
- // Class HV - Foreign Data Wrapper Error (SQL/MED)
- "HV000": "fdw_error",
- "HV005": "fdw_column_name_not_found",
- "HV002": "fdw_dynamic_parameter_value_needed",
- "HV010": "fdw_function_sequence_error",
- "HV021": "fdw_inconsistent_descriptor_information",
- "HV024": "fdw_invalid_attribute_value",
- "HV007": "fdw_invalid_column_name",
- "HV008": "fdw_invalid_column_number",
- "HV004": "fdw_invalid_data_type",
- "HV006": "fdw_invalid_data_type_descriptors",
- "HV091": "fdw_invalid_descriptor_field_identifier",
- "HV00B": "fdw_invalid_handle",
- "HV00C": "fdw_invalid_option_index",
- "HV00D": "fdw_invalid_option_name",
- "HV090": "fdw_invalid_string_length_or_buffer_length",
- "HV00A": "fdw_invalid_string_format",
- "HV009": "fdw_invalid_use_of_null_pointer",
- "HV014": "fdw_too_many_handles",
- "HV001": "fdw_out_of_memory",
- "HV00P": "fdw_no_schemas",
- "HV00J": "fdw_option_name_not_found",
- "HV00K": "fdw_reply_handle",
- "HV00Q": "fdw_schema_not_found",
- "HV00R": "fdw_table_not_found",
- "HV00L": "fdw_unable_to_create_execution",
- "HV00M": "fdw_unable_to_create_reply",
- "HV00N": "fdw_unable_to_establish_connection",
- // Class P0 - PL/pgSQL Error
- "P0000": "plpgsql_error",
- "P0001": "raise_exception",
- "P0002": "no_data_found",
- "P0003": "too_many_rows",
- // Class XX - Internal Error
- "XX000": "internal_error",
- "XX001": "data_corrupted",
- "XX002": "index_corrupted",
-}
-
-func parseError(r *readBuf) *Error {
- err := new(Error)
- for t := r.byte(); t != 0; t = r.byte() {
- msg := r.string()
- switch t {
- case 'S':
- err.Severity = msg
- case 'C':
- err.Code = ErrorCode(msg)
- case 'M':
- err.Message = msg
- case 'D':
- err.Detail = msg
- case 'H':
- err.Hint = msg
- case 'P':
- err.Position = msg
- case 'p':
- err.InternalPosition = msg
- case 'q':
- err.InternalQuery = msg
- case 'W':
- err.Where = msg
- case 's':
- err.Schema = msg
- case 't':
- err.Table = msg
- case 'c':
- err.Column = msg
- case 'd':
- err.DataTypeName = msg
- case 'n':
- err.Constraint = msg
- case 'F':
- err.File = msg
- case 'L':
- err.Line = msg
- case 'R':
- err.Routine = msg
- }
- }
- return err
-}
-
-// Fatal returns true if the Error Severity is fatal.
-func (err *Error) Fatal() bool {
- return err.Severity == Efatal
-}
-
-// Get implements the legacy PGError interface. New code should use the fields
-// of the Error struct directly.
-func (err *Error) Get(k byte) (v string) {
- switch k {
- case 'S':
- return err.Severity
- case 'C':
- return string(err.Code)
- case 'M':
- return err.Message
- case 'D':
- return err.Detail
- case 'H':
- return err.Hint
- case 'P':
- return err.Position
- case 'p':
- return err.InternalPosition
- case 'q':
- return err.InternalQuery
- case 'W':
- return err.Where
- case 's':
- return err.Schema
- case 't':
- return err.Table
- case 'c':
- return err.Column
- case 'd':
- return err.DataTypeName
- case 'n':
- return err.Constraint
- case 'F':
- return err.File
- case 'L':
- return err.Line
- case 'R':
- return err.Routine
- }
- return ""
-}
-
-func (err Error) Error() string {
- return "pq: " + err.Message
-}
-
-// PGError is an interface used by previous versions of pq. It is provided
-// only to support legacy code. New code should use the Error type.
-type PGError interface {
- Error() string
- Fatal() bool
- Get(k byte) (v string)
-}
-
-func errorf(s string, args ...interface{}) {
- panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
-}
-
-func errRecoverNoErrBadConn(err *error) {
- e := recover()
- if e == nil {
- // Do nothing
- return
- }
- var ok bool
- *err, ok = e.(error)
- if !ok {
- *err = fmt.Errorf("pq: unexpected error: %#v", e)
- }
-}
-
-func (c *conn) errRecover(err *error) {
- e := recover()
- switch v := e.(type) {
- case nil:
- // Do nothing
- case runtime.Error:
- c.bad = true
- panic(v)
- case *Error:
- if v.Fatal() {
- *err = driver.ErrBadConn
- } else {
- *err = v
- }
- case *net.OpError:
- *err = driver.ErrBadConn
- case error:
- if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
- *err = driver.ErrBadConn
- } else {
- *err = v
- }
-
- default:
- c.bad = true
- panic(fmt.Sprintf("unknown error: %#v", e))
- }
-
- // Any time we return ErrBadConn, we need to remember it since *Tx doesn't
- // mark the connection bad in database/sql.
- if *err == driver.ErrBadConn {
- c.bad = true
- }
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/hstore/hstore.go b/Godeps/_workspace/src/github.com/lib/pq/hstore/hstore.go
deleted file mode 100644
index 72d5abf51..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/hstore/hstore.go
+++ /dev/null
@@ -1,118 +0,0 @@
-package hstore
-
-import (
- "database/sql"
- "database/sql/driver"
- "strings"
-)
-
-// A wrapper for transferring Hstore values back and forth easily.
-type Hstore struct {
- Map map[string]sql.NullString
-}
-
-// escapes and quotes hstore keys/values
-// s should be a sql.NullString or string
-func hQuote(s interface{}) string {
- var str string
- switch v := s.(type) {
- case sql.NullString:
- if !v.Valid {
- return "NULL"
- }
- str = v.String
- case string:
- str = v
- default:
- panic("not a string or sql.NullString")
- }
-
- str = strings.Replace(str, "\\", "\\\\", -1)
- return `"` + strings.Replace(str, "\"", "\\\"", -1) + `"`
-}
-
-// Scan implements the Scanner interface.
-//
-// Note h.Map is reallocated before the scan to clear existing values. If the
-// hstore column's database value is NULL, then h.Map is set to nil instead.
-func (h *Hstore) Scan(value interface{}) error {
- if value == nil {
- h.Map = nil
- return nil
- }
- h.Map = make(map[string]sql.NullString)
- var b byte
- pair := [][]byte{{}, {}}
- pi := 0
- inQuote := false
- didQuote := false
- sawSlash := false
- bindex := 0
- for bindex, b = range value.([]byte) {
- if sawSlash {
- pair[pi] = append(pair[pi], b)
- sawSlash = false
- continue
- }
-
- switch b {
- case '\\':
- sawSlash = true
- continue
- case '"':
- inQuote = !inQuote
- if !didQuote {
- didQuote = true
- }
- continue
- default:
- if !inQuote {
- switch b {
- case ' ', '\t', '\n', '\r':
- continue
- case '=':
- continue
- case '>':
- pi = 1
- didQuote = false
- continue
- case ',':
- s := string(pair[1])
- if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
- h.Map[string(pair[0])] = sql.NullString{String: "", Valid: false}
- } else {
- h.Map[string(pair[0])] = sql.NullString{String: string(pair[1]), Valid: true}
- }
- pair[0] = []byte{}
- pair[1] = []byte{}
- pi = 0
- continue
- }
- }
- }
- pair[pi] = append(pair[pi], b)
- }
- if bindex > 0 {
- s := string(pair[1])
- if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
- h.Map[string(pair[0])] = sql.NullString{String: "", Valid: false}
- } else {
- h.Map[string(pair[0])] = sql.NullString{String: string(pair[1]), Valid: true}
- }
- }
- return nil
-}
-
-// Value implements the driver Valuer interface. Note if h.Map is nil, the
-// database column value will be set to NULL.
-func (h Hstore) Value() (driver.Value, error) {
- if h.Map == nil {
- return nil, nil
- }
- parts := []string{}
- for key, val := range h.Map {
- thispart := hQuote(key) + "=>" + hQuote(val)
- parts = append(parts, thispart)
- }
- return []byte(strings.Join(parts, ",")), nil
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go b/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go
deleted file mode 100644
index 5bc99f5c1..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-
-Below you will find a self-contained Go program which uses the LISTEN / NOTIFY
-mechanism to avoid polling the database while waiting for more work to arrive.
-
- //
- // You can see the program in action by defining a function similar to
- // the following:
- //
- // CREATE OR REPLACE FUNCTION public.get_work()
- // RETURNS bigint
- // LANGUAGE sql
- // AS $$
- // SELECT CASE WHEN random() >= 0.2 THEN int8 '1' END
- // $$
- // ;
-
- package main
-
- import (
- "database/sql"
- "fmt"
- "time"
-
- "github.com/lib/pq"
- )
-
- func doWork(db *sql.DB, work int64) {
- // work here
- }
-
- func getWork(db *sql.DB) {
- for {
- // get work from the database here
- var work sql.NullInt64
- err := db.QueryRow("SELECT get_work()").Scan(&work)
- if err != nil {
- fmt.Println("call to get_work() failed: ", err)
- time.Sleep(10 * time.Second)
- continue
- }
- if !work.Valid {
- // no more work to do
- fmt.Println("ran out of work")
- return
- }
-
- fmt.Println("starting work on ", work.Int64)
- go doWork(db, work.Int64)
- }
- }
-
- func waitForNotification(l *pq.Listener) {
- for {
- select {
- case <-l.Notify:
- fmt.Println("received notification, new work available")
- return
- case <-time.After(90 * time.Second):
- go func() {
- l.Ping()
- }()
- // Check if there's more work available, just in case it takes
- // a while for the Listener to notice connection loss and
- // reconnect.
- fmt.Println("received no work for 90 seconds, checking for new work")
- return
- }
- }
- }
-
- func main() {
- var conninfo string = ""
-
- db, err := sql.Open("postgres", conninfo)
- if err != nil {
- panic(err)
- }
-
- reportProblem := func(ev pq.ListenerEventType, err error) {
- if err != nil {
- fmt.Println(err.Error())
- }
- }
-
- listener := pq.NewListener(conninfo, 10 * time.Second, time.Minute, reportProblem)
- err = listener.Listen("getwork")
- if err != nil {
- panic(err)
- }
-
- fmt.Println("entering main loop")
- for {
- // process all available work before waiting for notifications
- getWork(db)
- waitForNotification(listener)
- }
- }
-
-
-*/
-package listen_example
diff --git a/Godeps/_workspace/src/github.com/lib/pq/notify.go b/Godeps/_workspace/src/github.com/lib/pq/notify.go
deleted file mode 100644
index 8cad57815..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/notify.go
+++ /dev/null
@@ -1,766 +0,0 @@
-package pq
-
-// Package pq is a pure Go Postgres driver for the database/sql package.
-// This module contains support for Postgres LISTEN/NOTIFY.
-
-import (
- "errors"
- "fmt"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// Notification represents a single notification from the database.
-type Notification struct {
- // Process ID (PID) of the notifying postgres backend.
- BePid int
- // Name of the channel the notification was sent on.
- Channel string
- // Payload, or the empty string if unspecified.
- Extra string
-}
-
-func recvNotification(r *readBuf) *Notification {
- bePid := r.int32()
- channel := r.string()
- extra := r.string()
-
- return &Notification{bePid, channel, extra}
-}
-
-const (
- connStateIdle int32 = iota
- connStateExpectResponse
- connStateExpectReadyForQuery
-)
-
-type message struct {
- typ byte
- err error
-}
-
-var errListenerConnClosed = errors.New("pq: ListenerConn has been closed")
-
-// ListenerConn is a low-level interface for waiting for notifications. You
-// should use Listener instead.
-type ListenerConn struct {
- // guards cn and err
- connectionLock sync.Mutex
- cn *conn
- err error
-
- connState int32
-
- // the sending goroutine will be holding this lock
- senderLock sync.Mutex
-
- notificationChan chan<- *Notification
-
- replyChan chan message
-}
-
-// Creates a new ListenerConn. Use NewListener instead.
-func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error) {
- cn, err := Open(name)
- if err != nil {
- return nil, err
- }
-
- l := &ListenerConn{
- cn: cn.(*conn),
- notificationChan: notificationChan,
- connState: connStateIdle,
- replyChan: make(chan message, 2),
- }
-
- go l.listenerConnMain()
-
- return l, nil
-}
-
-// We can only allow one goroutine at a time to be running a query on the
-// connection for various reasons, so the goroutine sending on the connection
-// must be holding senderLock.
-//
-// Returns an error if an unrecoverable error has occurred and the ListenerConn
-// should be abandoned.
-func (l *ListenerConn) acquireSenderLock() error {
- // we must acquire senderLock first to avoid deadlocks; see ExecSimpleQuery
- l.senderLock.Lock()
-
- l.connectionLock.Lock()
- err := l.err
- l.connectionLock.Unlock()
- if err != nil {
- l.senderLock.Unlock()
- return err
- }
- return nil
-}
-
-func (l *ListenerConn) releaseSenderLock() {
- l.senderLock.Unlock()
-}
-
-// setState advances the protocol state to newState. Returns false if moving
-// to that state from the current state is not allowed.
-func (l *ListenerConn) setState(newState int32) bool {
- var expectedState int32
-
- switch newState {
- case connStateIdle:
- expectedState = connStateExpectReadyForQuery
- case connStateExpectResponse:
- expectedState = connStateIdle
- case connStateExpectReadyForQuery:
- expectedState = connStateExpectResponse
- default:
- panic(fmt.Sprintf("unexpected listenerConnState %d", newState))
- }
-
- return atomic.CompareAndSwapInt32(&l.connState, expectedState, newState)
-}
-
-// Main logic is here: receive messages from the postgres backend, forward
-// notifications and query replies and keep the internal state in sync with the
-// protocol state. Returns when the connection has been lost, is about to go
-// away or should be discarded because we couldn't agree on the state with the
-// server backend.
-func (l *ListenerConn) listenerConnLoop() (err error) {
- defer errRecoverNoErrBadConn(&err)
-
- r := &readBuf{}
- for {
- t, err := l.cn.recvMessage(r)
- if err != nil {
- return err
- }
-
- switch t {
- case 'A':
- // recvNotification copies all the data so we don't need to worry
- // about the scratch buffer being overwritten.
- l.notificationChan <- recvNotification(r)
-
- case 'T', 'D':
- // only used by tests; ignore
-
- case 'E':
- // We might receive an ErrorResponse even when not in a query; it
- // is expected that the server will close the connection after
- // that, but we should make sure that the error we display is the
- // one from the stray ErrorResponse, not io.ErrUnexpectedEOF.
- if !l.setState(connStateExpectReadyForQuery) {
- return parseError(r)
- }
- l.replyChan <- message{t, parseError(r)}
-
- case 'C', 'I':
- if !l.setState(connStateExpectReadyForQuery) {
- // protocol out of sync
- return fmt.Errorf("unexpected CommandComplete")
- }
- // ExecSimpleQuery doesn't need to know about this message
-
- case 'Z':
- if !l.setState(connStateIdle) {
- // protocol out of sync
- return fmt.Errorf("unexpected ReadyForQuery")
- }
- l.replyChan <- message{t, nil}
-
- case 'N', 'S':
- // ignore
- default:
- return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t)
- }
- }
-}
-
-// This is the main routine for the goroutine receiving on the database
-// connection. Most of the main logic is in listenerConnLoop.
-func (l *ListenerConn) listenerConnMain() {
- err := l.listenerConnLoop()
-
- // listenerConnLoop terminated; we're done, but we still have to clean up.
- // Make sure nobody tries to start any new queries by making sure the err
- // pointer is set. It is important that we do not overwrite its value; a
- // connection could be closed by either this goroutine or one sending on
- // the connection -- whoever closes the connection is assumed to have the
- // more meaningful error message (as the other one will probably get
- // net.errClosed), so that goroutine sets the error we expose while the
- // other error is discarded. If the connection is lost while two
- // goroutines are operating on the socket, it probably doesn't matter which
- // error we expose so we don't try to do anything more complex.
- l.connectionLock.Lock()
- if l.err == nil {
- l.err = err
- }
- l.cn.Close()
- l.connectionLock.Unlock()
-
- // There might be a query in-flight; make sure nobody's waiting for a
- // response to it, since there's not going to be one.
- close(l.replyChan)
-
- // let the listener know we're done
- close(l.notificationChan)
-
- // this ListenerConn is done
-}
-
-// Send a LISTEN query to the server. See ExecSimpleQuery.
-func (l *ListenerConn) Listen(channel string) (bool, error) {
- return l.ExecSimpleQuery("LISTEN " + QuoteIdentifier(channel))
-}
-
-// Send an UNLISTEN query to the server. See ExecSimpleQuery.
-func (l *ListenerConn) Unlisten(channel string) (bool, error) {
- return l.ExecSimpleQuery("UNLISTEN " + QuoteIdentifier(channel))
-}
-
-// Send `UNLISTEN *` to the server. See ExecSimpleQuery.
-func (l *ListenerConn) UnlistenAll() (bool, error) {
- return l.ExecSimpleQuery("UNLISTEN *")
-}
-
-// Ping the remote server to make sure it's alive. Non-nil error means the
-// connection has failed and should be abandoned.
-func (l *ListenerConn) Ping() error {
- sent, err := l.ExecSimpleQuery("")
- if !sent {
- return err
- }
- if err != nil {
- // shouldn't happen
- panic(err)
- }
- return nil
-}
-
-// Attempt to send a query on the connection. Returns an error if sending the
-// query failed, and the caller should initiate closure of this connection.
-// The caller must be holding senderLock (see acquireSenderLock and
-// releaseSenderLock).
-func (l *ListenerConn) sendSimpleQuery(q string) (err error) {
- defer errRecoverNoErrBadConn(&err)
-
- // must set connection state before sending the query
- if !l.setState(connStateExpectResponse) {
- panic("two queries running at the same time")
- }
-
- // Can't use l.cn.writeBuf here because it uses the scratch buffer which
- // might get overwritten by listenerConnLoop.
- b := &writeBuf{
- buf: []byte("Q\x00\x00\x00\x00"),
- pos: 1,
- }
- b.string(q)
- l.cn.send(b)
-
- return nil
-}
-
-// Execute a "simple query" (i.e. one with no bindable parameters) on the
-// connection. The possible return values are:
-// 1) "executed" is true; the query was executed to completion on the
-// database server. If the query failed, err will be set to the error
-// returned by the database, otherwise err will be nil.
-// 2) If "executed" is false, the query could not be executed on the remote
-// server. err will be non-nil.
-//
-// After a call to ExecSimpleQuery has returned an executed=false value, the
-// connection has either been closed or will be closed shortly thereafter, and
-// all subsequently executed queries will return an error.
-func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) {
- if err = l.acquireSenderLock(); err != nil {
- return false, err
- }
- defer l.releaseSenderLock()
-
- err = l.sendSimpleQuery(q)
- if err != nil {
- // We can't know what state the protocol is in, so we need to abandon
- // this connection.
- l.connectionLock.Lock()
- // Set the error pointer if it hasn't been set already; see
- // listenerConnMain.
- if l.err == nil {
- l.err = err
- }
- l.connectionLock.Unlock()
- l.cn.c.Close()
- return false, err
- }
-
- // now we just wait for a reply..
- for {
- m, ok := <-l.replyChan
- if !ok {
- // We lost the connection to server, don't bother waiting for a
- // a response. err should have been set already.
- l.connectionLock.Lock()
- err := l.err
- l.connectionLock.Unlock()
- return false, err
- }
- switch m.typ {
- case 'Z':
- // sanity check
- if m.err != nil {
- panic("m.err != nil")
- }
- // done; err might or might not be set
- return true, err
-
- case 'E':
- // sanity check
- if m.err == nil {
- panic("m.err == nil")
- }
- // server responded with an error; ReadyForQuery to follow
- err = m.err
-
- default:
- return false, fmt.Errorf("unknown response for simple query: %q", m.typ)
- }
- }
-}
-
-func (l *ListenerConn) Close() error {
- l.connectionLock.Lock()
- if l.err != nil {
- l.connectionLock.Unlock()
- return errListenerConnClosed
- }
- l.err = errListenerConnClosed
- l.connectionLock.Unlock()
- // We can't send anything on the connection without holding senderLock.
- // Simply close the net.Conn to wake up everyone operating on it.
- return l.cn.c.Close()
-}
-
-// Err() returns the reason the connection was closed. It is not safe to call
-// this function until l.Notify has been closed.
-func (l *ListenerConn) Err() error {
- return l.err
-}
-
-var errListenerClosed = errors.New("pq: Listener has been closed")
-
-var ErrChannelAlreadyOpen = errors.New("pq: channel is already open")
-var ErrChannelNotOpen = errors.New("pq: channel is not open")
-
-type ListenerEventType int
-
-const (
- // Emitted only when the database connection has been initially
- // initialized. err will always be nil.
- ListenerEventConnected ListenerEventType = iota
-
- // Emitted after a database connection has been lost, either because of an
- // error or because Close has been called. err will be set to the reason
- // the database connection was lost.
- ListenerEventDisconnected
-
- // Emitted after a database connection has been re-established after
- // connection loss. err will always be nil. After this event has been
- // emitted, a nil pq.Notification is sent on the Listener.Notify channel.
- ListenerEventReconnected
-
- // Emitted after a connection to the database was attempted, but failed.
- // err will be set to an error describing why the connection attempt did
- // not succeed.
- ListenerEventConnectionAttemptFailed
-)
-
-type EventCallbackType func(event ListenerEventType, err error)
-
-// Listener provides an interface for listening to notifications from a
-// PostgreSQL database. For general usage information, see section
-// "Notifications".
-//
-// Listener can safely be used from concurrently running goroutines.
-type Listener struct {
- // Channel for receiving notifications from the database. In some cases a
- // nil value will be sent. See section "Notifications" above.
- Notify chan *Notification
-
- name string
- minReconnectInterval time.Duration
- maxReconnectInterval time.Duration
- eventCallback EventCallbackType
-
- lock sync.Mutex
- isClosed bool
- reconnectCond *sync.Cond
- cn *ListenerConn
- connNotificationChan <-chan *Notification
- channels map[string]struct{}
-}
-
-// NewListener creates a new database connection dedicated to LISTEN / NOTIFY.
-//
-// name should be set to a connection string to be used to establish the
-// database connection (see section "Connection String Parameters" above).
-//
-// minReconnectInterval controls the duration to wait before trying to
-// re-establish the database connection after connection loss. After each
-// consecutive failure this interval is doubled, until maxReconnectInterval is
-// reached. Successfully completing the connection establishment procedure
-// resets the interval back to minReconnectInterval.
-//
-// The last parameter eventCallback can be set to a function which will be
-// called by the Listener when the state of the underlying database connection
-// changes. This callback will be called by the goroutine which dispatches the
-// notifications over the Notify channel, so you should try to avoid doing
-// potentially time-consuming operations from the callback.
-func NewListener(name string,
- minReconnectInterval time.Duration,
- maxReconnectInterval time.Duration,
- eventCallback EventCallbackType) *Listener {
- l := &Listener{
- name: name,
- minReconnectInterval: minReconnectInterval,
- maxReconnectInterval: maxReconnectInterval,
- eventCallback: eventCallback,
-
- channels: make(map[string]struct{}),
-
- Notify: make(chan *Notification, 32),
- }
- l.reconnectCond = sync.NewCond(&l.lock)
-
- go l.listenerMain()
-
- return l
-}
-
-// Returns the notification channel for this listener. This is the same
-// channel as Notify, and will not be recreated during the life time of the
-// Listener.
-func (l *Listener) NotificationChannel() <-chan *Notification {
- return l.Notify
-}
-
-// Listen starts listening for notifications on a channel. Calls to this
-// function will block until an acknowledgement has been received from the
-// server. Note that Listener automatically re-establishes the connection
-// after connection loss, so this function may block indefinitely if the
-// connection can not be re-established.
-//
-// Listen will only fail in three conditions:
-// 1) The channel is already open. The returned error will be
-// ErrChannelAlreadyOpen.
-// 2) The query was executed on the remote server, but PostgreSQL returned an
-// error message in response to the query. The returned error will be a
-// pq.Error containing the information the server supplied.
-// 3) Close is called on the Listener before the request could be completed.
-//
-// The channel name is case-sensitive.
-func (l *Listener) Listen(channel string) error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- if l.isClosed {
- return errListenerClosed
- }
-
- // The server allows you to issue a LISTEN on a channel which is already
- // open, but it seems useful to be able to detect this case to spot for
- // mistakes in application logic. If the application genuinely does't
- // care, it can check the exported error and ignore it.
- _, exists := l.channels[channel]
- if exists {
- return ErrChannelAlreadyOpen
- }
-
- if l.cn != nil {
- // If gotResponse is true but error is set, the query was executed on
- // the remote server, but resulted in an error. This should be
- // relatively rare, so it's fine if we just pass the error to our
- // caller. However, if gotResponse is false, we could not complete the
- // query on the remote server and our underlying connection is about
- // to go away, so we only add relname to l.channels, and wait for
- // resync() to take care of the rest.
- gotResponse, err := l.cn.Listen(channel)
- if gotResponse && err != nil {
- return err
- }
- }
-
- l.channels[channel] = struct{}{}
- for l.cn == nil {
- l.reconnectCond.Wait()
- // we let go of the mutex for a while
- if l.isClosed {
- return errListenerClosed
- }
- }
-
- return nil
-}
-
-// Unlisten removes a channel from the Listener's channel list. Returns
-// ErrChannelNotOpen if the Listener is not listening on the specified channel.
-// Returns immediately with no error if there is no connection. Note that you
-// might still get notifications for this channel even after Unlisten has
-// returned.
-//
-// The channel name is case-sensitive.
-func (l *Listener) Unlisten(channel string) error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- if l.isClosed {
- return errListenerClosed
- }
-
- // Similarly to LISTEN, this is not an error in Postgres, but it seems
- // useful to distinguish from the normal conditions.
- _, exists := l.channels[channel]
- if !exists {
- return ErrChannelNotOpen
- }
-
- if l.cn != nil {
- // Similarly to Listen (see comment in that function), the caller
- // should only be bothered with an error if it came from the backend as
- // a response to our query.
- gotResponse, err := l.cn.Unlisten(channel)
- if gotResponse && err != nil {
- return err
- }
- }
-
- // Don't bother waiting for resync if there's no connection.
- delete(l.channels, channel)
- return nil
-}
-
-// UnlistenAll removes all channels from the Listener's channel list. Returns
-// immediately with no error if there is no connection. Note that you might
-// still get notifications for any of the deleted channels even after
-// UnlistenAll has returned.
-func (l *Listener) UnlistenAll() error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- if l.isClosed {
- return errListenerClosed
- }
-
- if l.cn != nil {
- // Similarly to Listen (see comment in that function), the caller
- // should only be bothered with an error if it came from the backend as
- // a response to our query.
- gotResponse, err := l.cn.UnlistenAll()
- if gotResponse && err != nil {
- return err
- }
- }
-
- // Don't bother waiting for resync if there's no connection.
- l.channels = make(map[string]struct{})
- return nil
-}
-
-// Ping the remote server to make sure it's alive. Non-nil return value means
-// that there is no active connection.
-func (l *Listener) Ping() error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- if l.isClosed {
- return errListenerClosed
- }
- if l.cn == nil {
- return errors.New("no connection")
- }
-
- return l.cn.Ping()
-}
-
-// Clean up after losing the server connection. Returns l.cn.Err(), which
-// should have the reason the connection was lost.
-func (l *Listener) disconnectCleanup() error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- // sanity check; can't look at Err() until the channel has been closed
- select {
- case _, ok := <-l.connNotificationChan:
- if ok {
- panic("connNotificationChan not closed")
- }
- default:
- panic("connNotificationChan not closed")
- }
-
- err := l.cn.Err()
- l.cn.Close()
- l.cn = nil
- return err
-}
-
-// Synchronize the list of channels we want to be listening on with the server
-// after the connection has been established.
-func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notification) error {
- doneChan := make(chan error)
- go func() {
- for channel := range l.channels {
- // If we got a response, return that error to our caller as it's
- // going to be more descriptive than cn.Err().
- gotResponse, err := cn.Listen(channel)
- if gotResponse && err != nil {
- doneChan <- err
- return
- }
-
- // If we couldn't reach the server, wait for notificationChan to
- // close and then return the error message from the connection, as
- // per ListenerConn's interface.
- if err != nil {
- for _ = range notificationChan {
- }
- doneChan <- cn.Err()
- return
- }
- }
- doneChan <- nil
- }()
-
- // Ignore notifications while synchronization is going on to avoid
- // deadlocks. We have to send a nil notification over Notify anyway as
- // we can't possibly know which notifications (if any) were lost while
- // the connection was down, so there's no reason to try and process
- // these messages at all.
- for {
- select {
- case _, ok := <-notificationChan:
- if !ok {
- notificationChan = nil
- }
-
- case err := <-doneChan:
- return err
- }
- }
-}
-
-// caller should NOT be holding l.lock
-func (l *Listener) closed() bool {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- return l.isClosed
-}
-
-func (l *Listener) connect() error {
- notificationChan := make(chan *Notification, 32)
- cn, err := NewListenerConn(l.name, notificationChan)
- if err != nil {
- return err
- }
-
- l.lock.Lock()
- defer l.lock.Unlock()
-
- err = l.resync(cn, notificationChan)
- if err != nil {
- cn.Close()
- return err
- }
-
- l.cn = cn
- l.connNotificationChan = notificationChan
- l.reconnectCond.Broadcast()
-
- return nil
-}
-
-// Close disconnects the Listener from the database and shuts it down.
-// Subsequent calls to its methods will return an error. Close returns an
-// error if the connection has already been closed.
-func (l *Listener) Close() error {
- l.lock.Lock()
- defer l.lock.Unlock()
-
- if l.isClosed {
- return errListenerClosed
- }
-
- if l.cn != nil {
- l.cn.Close()
- }
- l.isClosed = true
-
- return nil
-}
-
-func (l *Listener) emitEvent(event ListenerEventType, err error) {
- if l.eventCallback != nil {
- l.eventCallback(event, err)
- }
-}
-
-// Main logic here: maintain a connection to the server when possible, wait
-// for notifications and emit events.
-func (l *Listener) listenerConnLoop() {
- var nextReconnect time.Time
-
- reconnectInterval := l.minReconnectInterval
- for {
- for {
- err := l.connect()
- if err == nil {
- break
- }
-
- if l.closed() {
- return
- }
- l.emitEvent(ListenerEventConnectionAttemptFailed, err)
-
- time.Sleep(reconnectInterval)
- reconnectInterval *= 2
- if reconnectInterval > l.maxReconnectInterval {
- reconnectInterval = l.maxReconnectInterval
- }
- }
-
- if nextReconnect.IsZero() {
- l.emitEvent(ListenerEventConnected, nil)
- } else {
- l.emitEvent(ListenerEventReconnected, nil)
- l.Notify <- nil
- }
-
- reconnectInterval = l.minReconnectInterval
- nextReconnect = time.Now().Add(reconnectInterval)
-
- for {
- notification, ok := <-l.connNotificationChan
- if !ok {
- // lost connection, loop again
- break
- }
- l.Notify <- notification
- }
-
- err := l.disconnectCleanup()
- if l.closed() {
- return
- }
- l.emitEvent(ListenerEventDisconnected, err)
-
- time.Sleep(nextReconnect.Sub(time.Now()))
- }
-}
-
-func (l *Listener) listenerMain() {
- l.listenerConnLoop()
- close(l.Notify)
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/oid/doc.go b/Godeps/_workspace/src/github.com/lib/pq/oid/doc.go
deleted file mode 100644
index caaede248..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/oid/doc.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// Package oid contains OID constants
-// as defined by the Postgres server.
-package oid
-
-// Oid is a Postgres Object ID.
-type Oid uint32
diff --git a/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go b/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go
deleted file mode 100644
index cd4aea808..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// +build ignore
-
-// Generate the table of OID values
-// Run with 'go run gen.go'.
-package main
-
-import (
- "database/sql"
- "fmt"
- "log"
- "os"
- "os/exec"
-
- _ "github.com/lib/pq"
-)
-
-func main() {
- datname := os.Getenv("PGDATABASE")
- sslmode := os.Getenv("PGSSLMODE")
-
- if datname == "" {
- os.Setenv("PGDATABASE", "pqgotest")
- }
-
- if sslmode == "" {
- os.Setenv("PGSSLMODE", "disable")
- }
-
- db, err := sql.Open("postgres", "")
- if err != nil {
- log.Fatal(err)
- }
- cmd := exec.Command("gofmt")
- cmd.Stderr = os.Stderr
- w, err := cmd.StdinPipe()
- if err != nil {
- log.Fatal(err)
- }
- f, err := os.Create("types.go")
- if err != nil {
- log.Fatal(err)
- }
- cmd.Stdout = f
- err = cmd.Start()
- if err != nil {
- log.Fatal(err)
- }
- fmt.Fprintln(w, "// generated by 'go run gen.go'; do not edit")
- fmt.Fprintln(w, "\npackage oid")
- fmt.Fprintln(w, "const (")
- rows, err := db.Query(`
- SELECT typname, oid
- FROM pg_type WHERE oid < 10000
- ORDER BY oid;
- `)
- if err != nil {
- log.Fatal(err)
- }
- var name string
- var oid int
- for rows.Next() {
- err = rows.Scan(&name, &oid)
- if err != nil {
- log.Fatal(err)
- }
- fmt.Fprintf(w, "T_%s Oid = %d\n", name, oid)
- }
- if err = rows.Err(); err != nil {
- log.Fatal(err)
- }
- fmt.Fprintln(w, ")")
- w.Close()
- cmd.Wait()
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/oid/types.go b/Godeps/_workspace/src/github.com/lib/pq/oid/types.go
deleted file mode 100644
index 03df05a61..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/oid/types.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// generated by 'go run gen.go'; do not edit
-
-package oid
-
-const (
- T_bool Oid = 16
- T_bytea Oid = 17
- T_char Oid = 18
- T_name Oid = 19
- T_int8 Oid = 20
- T_int2 Oid = 21
- T_int2vector Oid = 22
- T_int4 Oid = 23
- T_regproc Oid = 24
- T_text Oid = 25
- T_oid Oid = 26
- T_tid Oid = 27
- T_xid Oid = 28
- T_cid Oid = 29
- T_oidvector Oid = 30
- T_pg_type Oid = 71
- T_pg_attribute Oid = 75
- T_pg_proc Oid = 81
- T_pg_class Oid = 83
- T_json Oid = 114
- T_xml Oid = 142
- T__xml Oid = 143
- T_pg_node_tree Oid = 194
- T__json Oid = 199
- T_smgr Oid = 210
- T_point Oid = 600
- T_lseg Oid = 601
- T_path Oid = 602
- T_box Oid = 603
- T_polygon Oid = 604
- T_line Oid = 628
- T__line Oid = 629
- T_cidr Oid = 650
- T__cidr Oid = 651
- T_float4 Oid = 700
- T_float8 Oid = 701
- T_abstime Oid = 702
- T_reltime Oid = 703
- T_tinterval Oid = 704
- T_unknown Oid = 705
- T_circle Oid = 718
- T__circle Oid = 719
- T_money Oid = 790
- T__money Oid = 791
- T_macaddr Oid = 829
- T_inet Oid = 869
- T__bool Oid = 1000
- T__bytea Oid = 1001
- T__char Oid = 1002
- T__name Oid = 1003
- T__int2 Oid = 1005
- T__int2vector Oid = 1006
- T__int4 Oid = 1007
- T__regproc Oid = 1008
- T__text Oid = 1009
- T__tid Oid = 1010
- T__xid Oid = 1011
- T__cid Oid = 1012
- T__oidvector Oid = 1013
- T__bpchar Oid = 1014
- T__varchar Oid = 1015
- T__int8 Oid = 1016
- T__point Oid = 1017
- T__lseg Oid = 1018
- T__path Oid = 1019
- T__box Oid = 1020
- T__float4 Oid = 1021
- T__float8 Oid = 1022
- T__abstime Oid = 1023
- T__reltime Oid = 1024
- T__tinterval Oid = 1025
- T__polygon Oid = 1027
- T__oid Oid = 1028
- T_aclitem Oid = 1033
- T__aclitem Oid = 1034
- T__macaddr Oid = 1040
- T__inet Oid = 1041
- T_bpchar Oid = 1042
- T_varchar Oid = 1043
- T_date Oid = 1082
- T_time Oid = 1083
- T_timestamp Oid = 1114
- T__timestamp Oid = 1115
- T__date Oid = 1182
- T__time Oid = 1183
- T_timestamptz Oid = 1184
- T__timestamptz Oid = 1185
- T_interval Oid = 1186
- T__interval Oid = 1187
- T__numeric Oid = 1231
- T_pg_database Oid = 1248
- T__cstring Oid = 1263
- T_timetz Oid = 1266
- T__timetz Oid = 1270
- T_bit Oid = 1560
- T__bit Oid = 1561
- T_varbit Oid = 1562
- T__varbit Oid = 1563
- T_numeric Oid = 1700
- T_refcursor Oid = 1790
- T__refcursor Oid = 2201
- T_regprocedure Oid = 2202
- T_regoper Oid = 2203
- T_regoperator Oid = 2204
- T_regclass Oid = 2205
- T_regtype Oid = 2206
- T__regprocedure Oid = 2207
- T__regoper Oid = 2208
- T__regoperator Oid = 2209
- T__regclass Oid = 2210
- T__regtype Oid = 2211
- T_record Oid = 2249
- T_cstring Oid = 2275
- T_any Oid = 2276
- T_anyarray Oid = 2277
- T_void Oid = 2278
- T_trigger Oid = 2279
- T_language_handler Oid = 2280
- T_internal Oid = 2281
- T_opaque Oid = 2282
- T_anyelement Oid = 2283
- T__record Oid = 2287
- T_anynonarray Oid = 2776
- T_pg_authid Oid = 2842
- T_pg_auth_members Oid = 2843
- T__txid_snapshot Oid = 2949
- T_uuid Oid = 2950
- T__uuid Oid = 2951
- T_txid_snapshot Oid = 2970
- T_fdw_handler Oid = 3115
- T_anyenum Oid = 3500
- T_tsvector Oid = 3614
- T_tsquery Oid = 3615
- T_gtsvector Oid = 3642
- T__tsvector Oid = 3643
- T__gtsvector Oid = 3644
- T__tsquery Oid = 3645
- T_regconfig Oid = 3734
- T__regconfig Oid = 3735
- T_regdictionary Oid = 3769
- T__regdictionary Oid = 3770
- T_anyrange Oid = 3831
- T_event_trigger Oid = 3838
- T_int4range Oid = 3904
- T__int4range Oid = 3905
- T_numrange Oid = 3906
- T__numrange Oid = 3907
- T_tsrange Oid = 3908
- T__tsrange Oid = 3909
- T_tstzrange Oid = 3910
- T__tstzrange Oid = 3911
- T_daterange Oid = 3912
- T__daterange Oid = 3913
- T_int8range Oid = 3926
- T__int8range Oid = 3927
-)
diff --git a/Godeps/_workspace/src/github.com/lib/pq/url.go b/Godeps/_workspace/src/github.com/lib/pq/url.go
deleted file mode 100644
index 9bac95c48..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/url.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package pq
-
-import (
- "fmt"
- nurl "net/url"
- "sort"
- "strings"
-)
-
-// ParseURL no longer needs to be used by clients of this library since supplying a URL as a
-// connection string to sql.Open() is now supported:
-//
-// sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full")
-//
-// It remains exported here for backwards-compatibility.
-//
-// ParseURL converts a url to a connection string for driver.Open.
-// Example:
-//
-// "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full"
-//
-// converts to:
-//
-// "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full"
-//
-// A minimal example:
-//
-// "postgres://"
-//
-// This will be blank, causing driver.Open to use all of the defaults
-func ParseURL(url string) (string, error) {
- u, err := nurl.Parse(url)
- if err != nil {
- return "", err
- }
-
- if u.Scheme != "postgres" && u.Scheme != "postgresql" {
- return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
- }
-
- var kvs []string
- escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`)
- accrue := func(k, v string) {
- if v != "" {
- kvs = append(kvs, k+"="+escaper.Replace(v))
- }
- }
-
- if u.User != nil {
- v := u.User.Username()
- accrue("user", v)
-
- v, _ = u.User.Password()
- accrue("password", v)
- }
-
- i := strings.Index(u.Host, ":")
- if i < 0 {
- accrue("host", u.Host)
- } else {
- accrue("host", u.Host[:i])
- accrue("port", u.Host[i+1:])
- }
-
- if u.Path != "" {
- accrue("dbname", u.Path[1:])
- }
-
- q := u.Query()
- for k := range q {
- accrue(k, q.Get(k))
- }
-
- sort.Strings(kvs) // Makes testing easier (not a performance concern)
- return strings.Join(kvs, " "), nil
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/user_posix.go b/Godeps/_workspace/src/github.com/lib/pq/user_posix.go
deleted file mode 100644
index e937d7d08..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/user_posix.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Package pq is a pure Go Postgres driver for the database/sql package.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package pq
-
-import (
- "os"
- "os/user"
-)
-
-func userCurrent() (string, error) {
- u, err := user.Current()
- if err == nil {
- return u.Username, nil
- }
-
- name := os.Getenv("USER")
- if name != "" {
- return name, nil
- }
-
- return "", ErrCouldNotDetectUsername
-}
diff --git a/Godeps/_workspace/src/github.com/lib/pq/user_windows.go b/Godeps/_workspace/src/github.com/lib/pq/user_windows.go
deleted file mode 100644
index 2b691267b..000000000
--- a/Godeps/_workspace/src/github.com/lib/pq/user_windows.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Package pq is a pure Go Postgres driver for the database/sql package.
-package pq
-
-import (
- "path/filepath"
- "syscall"
-)
-
-// Perform Windows user name lookup identically to libpq.
-//
-// The PostgreSQL code makes use of the legacy Win32 function
-// GetUserName, and that function has not been imported into stock Go.
-// GetUserNameEx is available though, the difference being that a
-// wider range of names are available. To get the output to be the
-// same as GetUserName, only the base (or last) component of the
-// result is returned.
-func userCurrent() (string, error) {
- pw_name := make([]uint16, 128)
- pwname_size := uint32(len(pw_name)) - 1
- err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size)
- if err != nil {
- return "", ErrCouldNotDetectUsername
- }
- s := syscall.UTF16ToString(pw_name)
- u := filepath.Base(s)
- return u, nil
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/Makefile b/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/Makefile
deleted file mode 100644
index 518a034f3..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2010 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include $(GOROOT)/src/Make.inc
-TARG=rsc.googlecode.com/hg/gf256
-GOFILES=gf256.go #rs.go
-include $(GOROOT)/src/Make.pkg
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/blog_test.go b/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/blog_test.go
deleted file mode 100644
index 12cc7deb0..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/blog_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains a straightforward implementation of
-// Reed-Solomon encoding, along with a benchmark.
-// It goes with http://research.swtch.com/field.
-//
-// For an optimized implementation, see gf256.go.
-
-package gf256
-
-import (
- "bytes"
- "fmt"
- "testing"
-)
-
-// BlogECC writes to check the error correcting code bytes
-// for data using the given Reed-Solomon parameters.
-func BlogECC(rs *RSEncoder, m []byte, check []byte) {
- if len(check) < rs.c {
- panic("gf256: invalid check byte length")
- }
- if rs.c == 0 {
- return
- }
-
- // The check bytes are the remainder after dividing
- // data padded with c zeros by the generator polynomial.
-
- // p = data padded with c zeros.
- var p []byte
- n := len(m) + rs.c
- if len(rs.p) >= n {
- p = rs.p
- } else {
- p = make([]byte, n)
- }
- copy(p, m)
- for i := len(m); i < len(p); i++ {
- p[i] = 0
- }
-
- gen := rs.gen
-
- // Divide p by gen, leaving the remainder in p[len(data):].
- // p[0] is the most significant term in p, and
- // gen[0] is the most significant term in the generator.
- for i := 0; i < len(m); i++ {
- k := f.Mul(p[i], f.Inv(gen[0])) // k = pi / g0
- // p -= k·g
- for j, g := range gen {
- p[i+j] = f.Add(p[i+j], f.Mul(k, g))
- }
- }
-
- copy(check, p[len(m):])
- rs.p = p
-}
-
-func BenchmarkBlogECC(b *testing.B) {
- data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
- check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
- out := make([]byte, len(check))
- rs := NewRSEncoder(f, len(check))
- for i := 0; i < b.N; i++ {
- BlogECC(rs, data, out)
- }
- b.SetBytes(int64(len(data)))
- if !bytes.Equal(out, check) {
- fmt.Printf("have %#v want %#v\n", out, check)
- }
-}
-
-func TestBlogECC(t *testing.T) {
- data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
- check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
- out := make([]byte, len(check))
- rs := NewRSEncoder(f, len(check))
- BlogECC(rs, data, out)
- if !bytes.Equal(out, check) {
- t.Errorf("have %x want %x", out, check)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256.go b/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256.go
deleted file mode 100644
index 34cc975a8..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256.go
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package gf256 implements arithmetic over the Galois Field GF(256).
-package gf256
-
-import "strconv"
-
-// A Field represents an instance of GF(256) defined by a specific polynomial.
-type Field struct {
- log [256]byte // log[0] is unused
- exp [510]byte
-}
-
-// NewField returns a new field corresponding to the polynomial poly
-// and generator α. The Reed-Solomon encoding in QR codes uses
-// polynomial 0x11d with generator 2.
-//
-// The choice of generator α only affects the Exp and Log operations.
-func NewField(poly, α int) *Field {
- if poly < 0x100 || poly >= 0x200 || reducible(poly) {
- panic("gf256: invalid polynomial: " + strconv.Itoa(poly))
- }
-
- var f Field
- x := 1
- for i := 0; i < 255; i++ {
- if x == 1 && i != 0 {
- panic("gf256: invalid generator " + strconv.Itoa(α) +
- " for polynomial " + strconv.Itoa(poly))
- }
- f.exp[i] = byte(x)
- f.exp[i+255] = byte(x)
- f.log[x] = byte(i)
- x = mul(x, α, poly)
- }
- f.log[0] = 255
- for i := 0; i < 255; i++ {
- if f.log[f.exp[i]] != byte(i) {
- panic("bad log")
- }
- if f.log[f.exp[i+255]] != byte(i) {
- panic("bad log")
- }
- }
- for i := 1; i < 256; i++ {
- if f.exp[f.log[i]] != byte(i) {
- panic("bad log")
- }
- }
-
- return &f
-}
-
-// nbit returns the number of significant in p.
-func nbit(p int) uint {
- n := uint(0)
- for ; p > 0; p >>= 1 {
- n++
- }
- return n
-}
-
-// polyDiv divides the polynomial p by q and returns the remainder.
-func polyDiv(p, q int) int {
- np := nbit(p)
- nq := nbit(q)
- for ; np >= nq; np-- {
- if p&(1<<(np-1)) != 0 {
- p ^= q << (np - nq)
- }
- }
- return p
-}
-
-// mul returns the product x*y mod poly, a GF(256) multiplication.
-func mul(x, y, poly int) int {
- z := 0
- for x > 0 {
- if x&1 != 0 {
- z ^= y
- }
- x >>= 1
- y <<= 1
- if y&0x100 != 0 {
- y ^= poly
- }
- }
- return z
-}
-
-// reducible reports whether p is reducible.
-func reducible(p int) bool {
- // Multiplying n-bit * n-bit produces (2n-1)-bit,
- // so if p is reducible, one of its factors must be
- // of np/2+1 bits or fewer.
- np := nbit(p)
- for q := 2; q < 1<<(np/2+1); q++ {
- if polyDiv(p, q) == 0 {
- return true
- }
- }
- return false
-}
-
-// Add returns the sum of x and y in the field.
-func (f *Field) Add(x, y byte) byte {
- return x ^ y
-}
-
-// Exp returns the the base-α exponential of e in the field.
-// If e < 0, Exp returns 0.
-func (f *Field) Exp(e int) byte {
- if e < 0 {
- return 0
- }
- return f.exp[e%255]
-}
-
-// Log returns the base-α logarithm of x in the field.
-// If x == 0, Log returns -1.
-func (f *Field) Log(x byte) int {
- if x == 0 {
- return -1
- }
- return int(f.log[x])
-}
-
-// Inv returns the multiplicative inverse of x in the field.
-// If x == 0, Inv returns 0.
-func (f *Field) Inv(x byte) byte {
- if x == 0 {
- return 0
- }
- return f.exp[255-f.log[x]]
-}
-
-// Mul returns the product of x and y in the field.
-func (f *Field) Mul(x, y byte) byte {
- if x == 0 || y == 0 {
- return 0
- }
- return f.exp[int(f.log[x])+int(f.log[y])]
-}
-
-// An RSEncoder implements Reed-Solomon encoding
-// over a given field using a given number of error correction bytes.
-type RSEncoder struct {
- f *Field
- c int
- gen []byte
- lgen []byte
- p []byte
-}
-
-func (f *Field) gen(e int) (gen, lgen []byte) {
- // p = 1
- p := make([]byte, e+1)
- p[e] = 1
-
- for i := 0; i < e; i++ {
- // p *= (x + Exp(i))
- // p[j] = p[j]*Exp(i) + p[j+1].
- c := f.Exp(i)
- for j := 0; j < e; j++ {
- p[j] = f.Mul(p[j], c) ^ p[j+1]
- }
- p[e] = f.Mul(p[e], c)
- }
-
- // lp = log p.
- lp := make([]byte, e+1)
- for i, c := range p {
- if c == 0 {
- lp[i] = 255
- } else {
- lp[i] = byte(f.Log(c))
- }
- }
-
- return p, lp
-}
-
-// NewRSEncoder returns a new Reed-Solomon encoder
-// over the given field and number of error correction bytes.
-func NewRSEncoder(f *Field, c int) *RSEncoder {
- gen, lgen := f.gen(c)
- return &RSEncoder{f: f, c: c, gen: gen, lgen: lgen}
-}
-
-// ECC writes to check the error correcting code bytes
-// for data using the given Reed-Solomon parameters.
-func (rs *RSEncoder) ECC(data []byte, check []byte) {
- if len(check) < rs.c {
- panic("gf256: invalid check byte length")
- }
- if rs.c == 0 {
- return
- }
-
- // The check bytes are the remainder after dividing
- // data padded with c zeros by the generator polynomial.
-
- // p = data padded with c zeros.
- var p []byte
- n := len(data) + rs.c
- if len(rs.p) >= n {
- p = rs.p
- } else {
- p = make([]byte, n)
- }
- copy(p, data)
- for i := len(data); i < len(p); i++ {
- p[i] = 0
- }
-
- // Divide p by gen, leaving the remainder in p[len(data):].
- // p[0] is the most significant term in p, and
- // gen[0] is the most significant term in the generator,
- // which is always 1.
- // To avoid repeated work, we store various values as
- // lv, not v, where lv = log[v].
- f := rs.f
- lgen := rs.lgen[1:]
- for i := 0; i < len(data); i++ {
- c := p[i]
- if c == 0 {
- continue
- }
- q := p[i+1:]
- exp := f.exp[f.log[c]:]
- for j, lg := range lgen {
- if lg != 255 { // lgen uses 255 for log 0
- q[j] ^= exp[lg]
- }
- }
- }
- copy(check, p[len(data):])
- rs.p = p
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256_test.go b/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256_test.go
deleted file mode 100644
index f77fa7d67..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/gf256/gf256_test.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gf256
-
-import (
- "bytes"
- "fmt"
- "testing"
-)
-
-var f = NewField(0x11d, 2) // x^8 + x^4 + x^3 + x^2 + 1
-
-func TestBasic(t *testing.T) {
- if f.Exp(0) != 1 || f.Exp(1) != 2 || f.Exp(255) != 1 {
- panic("bad Exp")
- }
-}
-
-func TestECC(t *testing.T) {
- data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
- check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
- out := make([]byte, len(check))
- rs := NewRSEncoder(f, len(check))
- rs.ECC(data, out)
- if !bytes.Equal(out, check) {
- t.Errorf("have %x want %x", out, check)
- }
-}
-
-func TestLinear(t *testing.T) {
- d1 := []byte{0x00, 0x00}
- c1 := []byte{0x00, 0x00}
- out := make([]byte, len(c1))
- rs := NewRSEncoder(f, len(c1))
- if rs.ECC(d1, out); !bytes.Equal(out, c1) {
- t.Errorf("ECBytes(%x, %d) = %x, want 0", d1, len(c1), out)
- }
- d2 := []byte{0x00, 0x01}
- c2 := make([]byte, 2)
- rs.ECC(d2, c2)
- d3 := []byte{0x00, 0x02}
- c3 := make([]byte, 2)
- rs.ECC(d3, c3)
- cx := make([]byte, 2)
- for i := range cx {
- cx[i] = c2[i] ^ c3[i]
- }
- d4 := []byte{0x00, 0x03}
- c4 := make([]byte, 2)
- rs.ECC(d4, c4)
- if !bytes.Equal(cx, c4) {
- t.Errorf("ECBytes(%x, 2) = %x\nECBytes(%x, 2) = %x\nxor = %x\nECBytes(%x, 2) = %x",
- d2, c2, d3, c3, cx, d4, c4)
- }
-}
-
-func TestGaussJordan(t *testing.T) {
- rs := NewRSEncoder(f, 2)
- m := make([][]byte, 16)
- for i := range m {
- m[i] = make([]byte, 4)
- m[i][i/8] = 1 << uint(i%8)
- rs.ECC(m[i][:2], m[i][2:])
- }
- if false {
- fmt.Printf("---\n")
- for _, row := range m {
- fmt.Printf("%x\n", row)
- }
- }
- b := []uint{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}
- for i := 0; i < 16; i++ {
- bi := b[i]
- if m[i][bi/8]&(1<<(7-bi%8)) == 0 {
- for j := i + 1; ; j++ {
- if j >= len(m) {
- t.Errorf("lost track for %d", bi)
- break
- }
- if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
- m[i], m[j] = m[j], m[i]
- break
- }
- }
- }
- for j := i + 1; j < len(m); j++ {
- if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
- for k := range m[j] {
- m[j][k] ^= m[i][k]
- }
- }
- }
- }
- if false {
- fmt.Printf("---\n")
- for _, row := range m {
- fmt.Printf("%x\n", row)
- }
- }
- for i := 15; i >= 0; i-- {
- bi := b[i]
- for j := i - 1; j >= 0; j-- {
- if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
- for k := range m[j] {
- m[j][k] ^= m[i][k]
- }
- }
- }
- }
- if false {
- fmt.Printf("---\n")
- for _, row := range m {
- fmt.Printf("%x", row)
- out := make([]byte, 2)
- if rs.ECC(row[:2], out); !bytes.Equal(out, row[2:]) {
- fmt.Printf(" - want %x", out)
- }
- fmt.Printf("\n")
- }
- }
-}
-
-func BenchmarkECC(b *testing.B) {
- data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
- check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
- out := make([]byte, len(check))
- rs := NewRSEncoder(f, len(check))
- for i := 0; i < b.N; i++ {
- rs.ECC(data, out)
- }
- b.SetBytes(int64(len(data)))
- if !bytes.Equal(out, check) {
- fmt.Printf("have %#v want %#v\n", out, check)
- }
-}
-
-func TestGen(t *testing.T) {
- for i := 0; i < 256; i++ {
- _, lg := f.gen(i)
- if lg[0] != 0 {
- t.Errorf("#%d: %x", i, lg)
- }
- }
-}
-
-func TestReducible(t *testing.T) {
- var count = []int{1, 2, 3, 6, 9, 18, 30, 56, 99, 186} // oeis.org/A1037
- for i, want := range count {
- n := 0
- for p := 1 << uint(i+2); p < 1<<uint(i+3); p++ {
- if !reducible(p) {
- n++
- }
- }
- if n != want {
- t.Errorf("#reducible(%d-bit) = %d, want %d", i+2, n, want)
- }
- }
-}
-
-func TestExhaustive(t *testing.T) {
- for poly := 0x100; poly < 0x200; poly++ {
- if reducible(poly) {
- continue
- }
- α := 2
- for !generates(α, poly) {
- α++
- }
- f := NewField(poly, α)
- for p := 0; p < 256; p++ {
- for q := 0; q < 256; q++ {
- fm := int(f.Mul(byte(p), byte(q)))
- pm := mul(p, q, poly)
- if fm != pm {
- t.Errorf("NewField(%#x).Mul(%#x, %#x) = %#x, want %#x", poly, p, q, fm, pm)
- }
- }
- }
- }
-}
-
-func generates(α, poly int) bool {
- x := α
- for i := 0; i < 254; i++ {
- if x == 1 {
- return false
- }
- x = mul(x, α, poly)
- }
- return true
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/Makefile b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/Makefile
deleted file mode 100644
index d00c470bb..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(GOROOT)/src/Make.inc
-TARG=rsc.googlecode.com/hg/qr
-GOFILES=qr.go png.go
-include $(GOROOT)/src/Make.pkg
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/Makefile b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/Makefile
deleted file mode 100644
index 5d1c4d307..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include $(GOROOT)/src/Make.inc
-
-TARG=rsc.googlecode.com/hg/qr/coding
-GOFILES=\
- qr.go\
-
-include $(GOROOT)/src/Make.pkg
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/gen.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/gen.go
deleted file mode 100644
index a3857f277..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/gen.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// +build ignore
-
-package main
-
-import "fmt"
-
-// tables from qrencode-3.1.1/qrspec.c
-
-var capacity = [41]struct {
- width int
- words int
- remainder int
- ec [4]int
-}{
- {0, 0, 0, [4]int{0, 0, 0, 0}},
- {21, 26, 0, [4]int{7, 10, 13, 17}}, // 1
- {25, 44, 7, [4]int{10, 16, 22, 28}},
- {29, 70, 7, [4]int{15, 26, 36, 44}},
- {33, 100, 7, [4]int{20, 36, 52, 64}},
- {37, 134, 7, [4]int{26, 48, 72, 88}}, // 5
- {41, 172, 7, [4]int{36, 64, 96, 112}},
- {45, 196, 0, [4]int{40, 72, 108, 130}},
- {49, 242, 0, [4]int{48, 88, 132, 156}},
- {53, 292, 0, [4]int{60, 110, 160, 192}},
- {57, 346, 0, [4]int{72, 130, 192, 224}}, //10
- {61, 404, 0, [4]int{80, 150, 224, 264}},
- {65, 466, 0, [4]int{96, 176, 260, 308}},
- {69, 532, 0, [4]int{104, 198, 288, 352}},
- {73, 581, 3, [4]int{120, 216, 320, 384}},
- {77, 655, 3, [4]int{132, 240, 360, 432}}, //15
- {81, 733, 3, [4]int{144, 280, 408, 480}},
- {85, 815, 3, [4]int{168, 308, 448, 532}},
- {89, 901, 3, [4]int{180, 338, 504, 588}},
- {93, 991, 3, [4]int{196, 364, 546, 650}},
- {97, 1085, 3, [4]int{224, 416, 600, 700}}, //20
- {101, 1156, 4, [4]int{224, 442, 644, 750}},
- {105, 1258, 4, [4]int{252, 476, 690, 816}},
- {109, 1364, 4, [4]int{270, 504, 750, 900}},
- {113, 1474, 4, [4]int{300, 560, 810, 960}},
- {117, 1588, 4, [4]int{312, 588, 870, 1050}}, //25
- {121, 1706, 4, [4]int{336, 644, 952, 1110}},
- {125, 1828, 4, [4]int{360, 700, 1020, 1200}},
- {129, 1921, 3, [4]int{390, 728, 1050, 1260}},
- {133, 2051, 3, [4]int{420, 784, 1140, 1350}},
- {137, 2185, 3, [4]int{450, 812, 1200, 1440}}, //30
- {141, 2323, 3, [4]int{480, 868, 1290, 1530}},
- {145, 2465, 3, [4]int{510, 924, 1350, 1620}},
- {149, 2611, 3, [4]int{540, 980, 1440, 1710}},
- {153, 2761, 3, [4]int{570, 1036, 1530, 1800}},
- {157, 2876, 0, [4]int{570, 1064, 1590, 1890}}, //35
- {161, 3034, 0, [4]int{600, 1120, 1680, 1980}},
- {165, 3196, 0, [4]int{630, 1204, 1770, 2100}},
- {169, 3362, 0, [4]int{660, 1260, 1860, 2220}},
- {173, 3532, 0, [4]int{720, 1316, 1950, 2310}},
- {177, 3706, 0, [4]int{750, 1372, 2040, 2430}}, //40
-}
-
-var eccTable = [41][4][2]int{
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}},
- {{1, 0}, {1, 0}, {1, 0}, {1, 0}}, // 1
- {{1, 0}, {1, 0}, {1, 0}, {1, 0}},
- {{1, 0}, {1, 0}, {2, 0}, {2, 0}},
- {{1, 0}, {2, 0}, {2, 0}, {4, 0}},
- {{1, 0}, {2, 0}, {2, 2}, {2, 2}}, // 5
- {{2, 0}, {4, 0}, {4, 0}, {4, 0}},
- {{2, 0}, {4, 0}, {2, 4}, {4, 1}},
- {{2, 0}, {2, 2}, {4, 2}, {4, 2}},
- {{2, 0}, {3, 2}, {4, 4}, {4, 4}},
- {{2, 2}, {4, 1}, {6, 2}, {6, 2}}, //10
- {{4, 0}, {1, 4}, {4, 4}, {3, 8}},
- {{2, 2}, {6, 2}, {4, 6}, {7, 4}},
- {{4, 0}, {8, 1}, {8, 4}, {12, 4}},
- {{3, 1}, {4, 5}, {11, 5}, {11, 5}},
- {{5, 1}, {5, 5}, {5, 7}, {11, 7}}, //15
- {{5, 1}, {7, 3}, {15, 2}, {3, 13}},
- {{1, 5}, {10, 1}, {1, 15}, {2, 17}},
- {{5, 1}, {9, 4}, {17, 1}, {2, 19}},
- {{3, 4}, {3, 11}, {17, 4}, {9, 16}},
- {{3, 5}, {3, 13}, {15, 5}, {15, 10}}, //20
- {{4, 4}, {17, 0}, {17, 6}, {19, 6}},
- {{2, 7}, {17, 0}, {7, 16}, {34, 0}},
- {{4, 5}, {4, 14}, {11, 14}, {16, 14}},
- {{6, 4}, {6, 14}, {11, 16}, {30, 2}},
- {{8, 4}, {8, 13}, {7, 22}, {22, 13}}, //25
- {{10, 2}, {19, 4}, {28, 6}, {33, 4}},
- {{8, 4}, {22, 3}, {8, 26}, {12, 28}},
- {{3, 10}, {3, 23}, {4, 31}, {11, 31}},
- {{7, 7}, {21, 7}, {1, 37}, {19, 26}},
- {{5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
- {{13, 3}, {2, 29}, {42, 1}, {23, 28}},
- {{17, 0}, {10, 23}, {10, 35}, {19, 35}},
- {{17, 1}, {14, 21}, {29, 19}, {11, 46}},
- {{13, 6}, {14, 23}, {44, 7}, {59, 1}},
- {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
- {{6, 14}, {6, 34}, {46, 10}, {2, 64}},
- {{17, 4}, {29, 14}, {49, 10}, {24, 46}},
- {{4, 18}, {13, 32}, {48, 14}, {42, 32}},
- {{20, 4}, {40, 7}, {43, 22}, {10, 67}},
- {{19, 6}, {18, 31}, {34, 34}, {20, 61}}, //40
-}
-
-var align = [41][2]int{
- {0, 0},
- {0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
- {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
- {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
- {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
- {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
- {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
- {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
- {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
-}
-
-var versionPattern = [41]int{
- 0,
- 0, 0, 0, 0, 0, 0,
- 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
- 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
- 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
- 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
- 0x27541, 0x28c69,
-}
-
-func main() {
- fmt.Printf("\t{},\n")
- for i := 1; i <= 40; i++ {
- apos := align[i][0] - 2
- if apos < 0 {
- apos = 100
- }
- astride := align[i][1] - align[i][0]
- if astride < 1 {
- astride = 100
- }
- fmt.Printf("\t{%v, %v, %v, %#x, [4]level{{%v, %v}, {%v, %v}, {%v, %v}, {%v, %v}}}, // %v\n",
- apos, astride, capacity[i].words,
- versionPattern[i],
- eccTable[i][0][0]+eccTable[i][0][1],
- float64(capacity[i].ec[0])/float64(eccTable[i][0][0]+eccTable[i][0][1]),
- eccTable[i][1][0]+eccTable[i][1][1],
- float64(capacity[i].ec[1])/float64(eccTable[i][1][0]+eccTable[i][1][1]),
- eccTable[i][2][0]+eccTable[i][2][1],
- float64(capacity[i].ec[2])/float64(eccTable[i][2][0]+eccTable[i][2][1]),
- eccTable[i][3][0]+eccTable[i][3][1],
- float64(capacity[i].ec[3])/float64(eccTable[i][3][0]+eccTable[i][3][1]),
- i,
- )
- }
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go
deleted file mode 100644
index 35711a4eb..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go
+++ /dev/null
@@ -1,815 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package coding implements low-level QR coding details.
-package coding
-
-import (
- "fmt"
- "strconv"
- "strings"
-
- "github.com/mattermost/rsc/gf256"
-)
-
-// Field is the field for QR error correction.
-var Field = gf256.NewField(0x11d, 2)
-
-// A Version represents a QR version.
-// The version specifies the size of the QR code:
-// a QR code with version v has 4v+17 pixels on a side.
-// Versions number from 1 to 40: the larger the version,
-// the more information the code can store.
-type Version int
-
-const MinVersion = 1
-const MaxVersion = 40
-
-func (v Version) String() string {
- return strconv.Itoa(int(v))
-}
-
-func (v Version) sizeClass() int {
- if v <= 9 {
- return 0
- }
- if v <= 26 {
- return 1
- }
- return 2
-}
-
-// DataBytes returns the number of data bytes that can be
-// stored in a QR code with the given version and level.
-func (v Version) DataBytes(l Level) int {
- vt := &vtab[v]
- lev := &vt.level[l]
- return vt.bytes - lev.nblock*lev.check
-}
-
-// Encoding implements a QR data encoding scheme.
-// The implementations--Numeric, Alphanumeric, and String--specify
-// the character set and the mapping from UTF-8 to code bits.
-// The more restrictive the mode, the fewer code bits are needed.
-type Encoding interface {
- Check() error
- Bits(v Version) int
- Encode(b *Bits, v Version)
-}
-
-type Bits struct {
- b []byte
- nbit int
-}
-
-func (b *Bits) Reset() {
- b.b = b.b[:0]
- b.nbit = 0
-}
-
-func (b *Bits) Bits() int {
- return b.nbit
-}
-
-func (b *Bits) Bytes() []byte {
- if b.nbit%8 != 0 {
- panic("fractional byte")
- }
- return b.b
-}
-
-func (b *Bits) Append(p []byte) {
- if b.nbit%8 != 0 {
- panic("fractional byte")
- }
- b.b = append(b.b, p...)
- b.nbit += 8 * len(p)
-}
-
-func (b *Bits) Write(v uint, nbit int) {
- for nbit > 0 {
- n := nbit
- if n > 8 {
- n = 8
- }
- if b.nbit%8 == 0 {
- b.b = append(b.b, 0)
- } else {
- m := -b.nbit & 7
- if n > m {
- n = m
- }
- }
- b.nbit += n
- sh := uint(nbit - n)
- b.b[len(b.b)-1] |= uint8(v >> sh << uint(-b.nbit&7))
- v -= v >> sh << sh
- nbit -= n
- }
-}
-
-// Num is the encoding for numeric data.
-// The only valid characters are the decimal digits 0 through 9.
-type Num string
-
-func (s Num) String() string {
- return fmt.Sprintf("Num(%#q)", string(s))
-}
-
-func (s Num) Check() error {
- for _, c := range s {
- if c < '0' || '9' < c {
- return fmt.Errorf("non-numeric string %#q", string(s))
- }
- }
- return nil
-}
-
-var numLen = [3]int{10, 12, 14}
-
-func (s Num) Bits(v Version) int {
- return 4 + numLen[v.sizeClass()] + (10*len(s)+2)/3
-}
-
-func (s Num) Encode(b *Bits, v Version) {
- b.Write(1, 4)
- b.Write(uint(len(s)), numLen[v.sizeClass()])
- var i int
- for i = 0; i+3 <= len(s); i += 3 {
- w := uint(s[i]-'0')*100 + uint(s[i+1]-'0')*10 + uint(s[i+2]-'0')
- b.Write(w, 10)
- }
- switch len(s) - i {
- case 1:
- w := uint(s[i] - '0')
- b.Write(w, 4)
- case 2:
- w := uint(s[i]-'0')*10 + uint(s[i+1]-'0')
- b.Write(w, 7)
- }
-}
-
-// Alpha is the encoding for alphanumeric data.
-// The valid characters are 0-9A-Z$%*+-./: and space.
-type Alpha string
-
-const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
-
-func (s Alpha) String() string {
- return fmt.Sprintf("Alpha(%#q)", string(s))
-}
-
-func (s Alpha) Check() error {
- for _, c := range s {
- if strings.IndexRune(alphabet, c) < 0 {
- return fmt.Errorf("non-alphanumeric string %#q", string(s))
- }
- }
- return nil
-}
-
-var alphaLen = [3]int{9, 11, 13}
-
-func (s Alpha) Bits(v Version) int {
- return 4 + alphaLen[v.sizeClass()] + (11*len(s)+1)/2
-}
-
-func (s Alpha) Encode(b *Bits, v Version) {
- b.Write(2, 4)
- b.Write(uint(len(s)), alphaLen[v.sizeClass()])
- var i int
- for i = 0; i+2 <= len(s); i += 2 {
- w := uint(strings.IndexRune(alphabet, rune(s[i])))*45 +
- uint(strings.IndexRune(alphabet, rune(s[i+1])))
- b.Write(w, 11)
- }
-
- if i < len(s) {
- w := uint(strings.IndexRune(alphabet, rune(s[i])))
- b.Write(w, 6)
- }
-}
-
-// String is the encoding for 8-bit data. All bytes are valid.
-type String string
-
-func (s String) String() string {
- return fmt.Sprintf("String(%#q)", string(s))
-}
-
-func (s String) Check() error {
- return nil
-}
-
-var stringLen = [3]int{8, 16, 16}
-
-func (s String) Bits(v Version) int {
- return 4 + stringLen[v.sizeClass()] + 8*len(s)
-}
-
-func (s String) Encode(b *Bits, v Version) {
- b.Write(4, 4)
- b.Write(uint(len(s)), stringLen[v.sizeClass()])
- for i := 0; i < len(s); i++ {
- b.Write(uint(s[i]), 8)
- }
-}
-
-// A Pixel describes a single pixel in a QR code.
-type Pixel uint32
-
-const (
- Black Pixel = 1 << iota
- Invert
-)
-
-func (p Pixel) Offset() uint {
- return uint(p >> 6)
-}
-
-func OffsetPixel(o uint) Pixel {
- return Pixel(o << 6)
-}
-
-func (r PixelRole) Pixel() Pixel {
- return Pixel(r << 2)
-}
-
-func (p Pixel) Role() PixelRole {
- return PixelRole(p>>2) & 15
-}
-
-func (p Pixel) String() string {
- s := p.Role().String()
- if p&Black != 0 {
- s += "+black"
- }
- if p&Invert != 0 {
- s += "+invert"
- }
- s += "+" + strconv.FormatUint(uint64(p.Offset()), 10)
- return s
-}
-
-// A PixelRole describes the role of a QR pixel.
-type PixelRole uint32
-
-const (
- _ PixelRole = iota
- Position // position squares (large)
- Alignment // alignment squares (small)
- Timing // timing strip between position squares
- Format // format metadata
- PVersion // version pattern
- Unused // unused pixel
- Data // data bit
- Check // error correction check bit
- Extra
-)
-
-var roles = []string{
- "",
- "position",
- "alignment",
- "timing",
- "format",
- "pversion",
- "unused",
- "data",
- "check",
- "extra",
-}
-
-func (r PixelRole) String() string {
- if Position <= r && r <= Check {
- return roles[r]
- }
- return strconv.Itoa(int(r))
-}
-
-// A Level represents a QR error correction level.
-// From least to most tolerant of errors, they are L, M, Q, H.
-type Level int
-
-const (
- L Level = iota
- M
- Q
- H
-)
-
-func (l Level) String() string {
- if L <= l && l <= H {
- return "LMQH"[l : l+1]
- }
- return strconv.Itoa(int(l))
-}
-
-// A Code is a square pixel grid.
-type Code struct {
- Bitmap []byte // 1 is black, 0 is white
- Size int // number of pixels on a side
- Stride int // number of bytes per row
-}
-
-func (c *Code) Black(x, y int) bool {
- return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
- c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
-}
-
-// A Mask describes a mask that is applied to the QR
-// code to avoid QR artifacts being interpreted as
-// alignment and timing patterns (such as the squares
-// in the corners). Valid masks are integers from 0 to 7.
-type Mask int
-
-// http://www.swetake.com/qr/qr5_en.html
-var mfunc = []func(int, int) bool{
- func(i, j int) bool { return (i+j)%2 == 0 },
- func(i, j int) bool { return i%2 == 0 },
- func(i, j int) bool { return j%3 == 0 },
- func(i, j int) bool { return (i+j)%3 == 0 },
- func(i, j int) bool { return (i/2+j/3)%2 == 0 },
- func(i, j int) bool { return i*j%2+i*j%3 == 0 },
- func(i, j int) bool { return (i*j%2+i*j%3)%2 == 0 },
- func(i, j int) bool { return (i*j%3+(i+j)%2)%2 == 0 },
-}
-
-func (m Mask) Invert(y, x int) bool {
- if m < 0 {
- return false
- }
- return mfunc[m](y, x)
-}
-
-// A Plan describes how to construct a QR code
-// with a specific version, level, and mask.
-type Plan struct {
- Version Version
- Level Level
- Mask Mask
-
- DataBytes int // number of data bytes
- CheckBytes int // number of error correcting (checksum) bytes
- Blocks int // number of data blocks
-
- Pixel [][]Pixel // pixel map
-}
-
-// NewPlan returns a Plan for a QR code with the given
-// version, level, and mask.
-func NewPlan(version Version, level Level, mask Mask) (*Plan, error) {
- p, err := vplan(version)
- if err != nil {
- return nil, err
- }
- if err := fplan(level, mask, p); err != nil {
- return nil, err
- }
- if err := lplan(version, level, p); err != nil {
- return nil, err
- }
- if err := mplan(mask, p); err != nil {
- return nil, err
- }
- return p, nil
-}
-
-func (b *Bits) Pad(n int) {
- if n < 0 {
- panic("qr: invalid pad size")
- }
- if n <= 4 {
- b.Write(0, n)
- } else {
- b.Write(0, 4)
- n -= 4
- n -= -b.Bits() & 7
- b.Write(0, -b.Bits()&7)
- pad := n / 8
- for i := 0; i < pad; i += 2 {
- b.Write(0xec, 8)
- if i+1 >= pad {
- break
- }
- b.Write(0x11, 8)
- }
- }
-}
-
-func (b *Bits) AddCheckBytes(v Version, l Level) {
- nd := v.DataBytes(l)
- if b.nbit < nd*8 {
- b.Pad(nd*8 - b.nbit)
- }
- if b.nbit != nd*8 {
- panic("qr: too much data")
- }
-
- dat := b.Bytes()
- vt := &vtab[v]
- lev := &vt.level[l]
- db := nd / lev.nblock
- extra := nd % lev.nblock
- chk := make([]byte, lev.check)
- rs := gf256.NewRSEncoder(Field, lev.check)
- for i := 0; i < lev.nblock; i++ {
- if i == lev.nblock-extra {
- db++
- }
- rs.ECC(dat[:db], chk)
- b.Append(chk)
- dat = dat[db:]
- }
-
- if len(b.Bytes()) != vt.bytes {
- panic("qr: internal error")
- }
-}
-
-func (p *Plan) Encode(text ...Encoding) (*Code, error) {
- var b Bits
- for _, t := range text {
- if err := t.Check(); err != nil {
- return nil, err
- }
- t.Encode(&b, p.Version)
- }
- if b.Bits() > p.DataBytes*8 {
- return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", b.Bits(), p.DataBytes*8)
- }
- b.AddCheckBytes(p.Version, p.Level)
- bytes := b.Bytes()
-
- // Now we have the checksum bytes and the data bytes.
- // Construct the actual code.
- c := &Code{Size: len(p.Pixel), Stride: (len(p.Pixel) + 7) &^ 7}
- c.Bitmap = make([]byte, c.Stride*c.Size)
- crow := c.Bitmap
- for _, row := range p.Pixel {
- for x, pix := range row {
- switch pix.Role() {
- case Data, Check:
- o := pix.Offset()
- if bytes[o/8]&(1<<uint(7-o&7)) != 0 {
- pix ^= Black
- }
- }
- if pix&Black != 0 {
- crow[x/8] |= 1 << uint(7-x&7)
- }
- }
- crow = crow[c.Stride:]
- }
- return c, nil
-}
-
-// A version describes metadata associated with a version.
-type version struct {
- apos int
- astride int
- bytes int
- pattern int
- level [4]level
-}
-
-type level struct {
- nblock int
- check int
-}
-
-var vtab = []version{
- {},
- {100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}}, // 1
- {16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}}, // 2
- {20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}}, // 3
- {24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}}, // 4
- {28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}}, // 5
- {32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}}, // 6
- {20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}}, // 7
- {22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}}, // 8
- {24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}}, // 9
- {26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}}, // 10
- {28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}}, // 11
- {30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}}, // 12
- {32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}}, // 13
- {24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}}, // 14
- {24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}}, // 15
- {24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}}, // 16
- {28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}}, // 17
- {28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}}, // 18
- {28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}}, // 19
- {32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}}, // 20
- {26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}}, // 21
- {24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}}, // 22
- {28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}}, // 23
- {26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24
- {30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25
- {28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26
- {32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27
- {24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28
- {28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29
- {24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30
- {28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31
- {32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32
- {28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33
- {32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34
- {28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35
- {22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36
- {26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37
- {30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38
- {24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39
- {28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40
-}
-
-func grid(siz int) [][]Pixel {
- m := make([][]Pixel, siz)
- pix := make([]Pixel, siz*siz)
- for i := range m {
- m[i], pix = pix[:siz], pix[siz:]
- }
- return m
-}
-
-// vplan creates a Plan for the given version.
-func vplan(v Version) (*Plan, error) {
- p := &Plan{Version: v}
- if v < 1 || v > 40 {
- return nil, fmt.Errorf("invalid QR version %d", int(v))
- }
- siz := 17 + int(v)*4
- m := grid(siz)
- p.Pixel = m
-
- // Timing markers (overwritten by boxes).
- const ti = 6 // timing is in row/column 6 (counting from 0)
- for i := range m {
- p := Timing.Pixel()
- if i&1 == 0 {
- p |= Black
- }
- m[i][ti] = p
- m[ti][i] = p
- }
-
- // Position boxes.
- posBox(m, 0, 0)
- posBox(m, siz-7, 0)
- posBox(m, 0, siz-7)
-
- // Alignment boxes.
- info := &vtab[v]
- for x := 4; x+5 < siz; {
- for y := 4; y+5 < siz; {
- // don't overwrite timing markers
- if (x < 7 && y < 7) || (x < 7 && y+5 >= siz-7) || (x+5 >= siz-7 && y < 7) {
- } else {
- alignBox(m, x, y)
- }
- if y == 4 {
- y = info.apos
- } else {
- y += info.astride
- }
- }
- if x == 4 {
- x = info.apos
- } else {
- x += info.astride
- }
- }
-
- // Version pattern.
- pat := vtab[v].pattern
- if pat != 0 {
- v := pat
- for x := 0; x < 6; x++ {
- for y := 0; y < 3; y++ {
- p := PVersion.Pixel()
- if v&1 != 0 {
- p |= Black
- }
- m[siz-11+y][x] = p
- m[x][siz-11+y] = p
- v >>= 1
- }
- }
- }
-
- // One lonely black pixel
- m[siz-8][8] = Unused.Pixel() | Black
-
- return p, nil
-}
-
-// fplan adds the format pixels
-func fplan(l Level, m Mask, p *Plan) error {
- // Format pixels.
- fb := uint32(l^1) << 13 // level: L=01, M=00, Q=11, H=10
- fb |= uint32(m) << 10 // mask
- const formatPoly = 0x537
- rem := fb
- for i := 14; i >= 10; i-- {
- if rem&(1<<uint(i)) != 0 {
- rem ^= formatPoly << uint(i-10)
- }
- }
- fb |= rem
- invert := uint32(0x5412)
- siz := len(p.Pixel)
- for i := uint(0); i < 15; i++ {
- pix := Format.Pixel() + OffsetPixel(i)
- if (fb>>i)&1 == 1 {
- pix |= Black
- }
- if (invert>>i)&1 == 1 {
- pix ^= Invert | Black
- }
- // top left
- switch {
- case i < 6:
- p.Pixel[i][8] = pix
- case i < 8:
- p.Pixel[i+1][8] = pix
- case i < 9:
- p.Pixel[8][7] = pix
- default:
- p.Pixel[8][14-i] = pix
- }
- // bottom right
- switch {
- case i < 8:
- p.Pixel[8][siz-1-int(i)] = pix
- default:
- p.Pixel[siz-1-int(14-i)][8] = pix
- }
- }
- return nil
-}
-
-// lplan edits a version-only Plan to add information
-// about the error correction levels.
-func lplan(v Version, l Level, p *Plan) error {
- p.Level = l
-
- nblock := vtab[v].level[l].nblock
- ne := vtab[v].level[l].check
- nde := (vtab[v].bytes - ne*nblock) / nblock
- extra := (vtab[v].bytes - ne*nblock) % nblock
- dataBits := (nde*nblock + extra) * 8
- checkBits := ne * nblock * 8
-
- p.DataBytes = vtab[v].bytes - ne*nblock
- p.CheckBytes = ne * nblock
- p.Blocks = nblock
-
- // Make data + checksum pixels.
- data := make([]Pixel, dataBits)
- for i := range data {
- data[i] = Data.Pixel() | OffsetPixel(uint(i))
- }
- check := make([]Pixel, checkBits)
- for i := range check {
- check[i] = Check.Pixel() | OffsetPixel(uint(i+dataBits))
- }
-
- // Split into blocks.
- dataList := make([][]Pixel, nblock)
- checkList := make([][]Pixel, nblock)
- for i := 0; i < nblock; i++ {
- // The last few blocks have an extra data byte (8 pixels).
- nd := nde
- if i >= nblock-extra {
- nd++
- }
- dataList[i], data = data[0:nd*8], data[nd*8:]
- checkList[i], check = check[0:ne*8], check[ne*8:]
- }
- if len(data) != 0 || len(check) != 0 {
- panic("data/check math")
- }
-
- // Build up bit sequence, taking first byte of each block,
- // then second byte, and so on. Then checksums.
- bits := make([]Pixel, dataBits+checkBits)
- dst := bits
- for i := 0; i < nde+1; i++ {
- for _, b := range dataList {
- if i*8 < len(b) {
- copy(dst, b[i*8:(i+1)*8])
- dst = dst[8:]
- }
- }
- }
- for i := 0; i < ne; i++ {
- for _, b := range checkList {
- if i*8 < len(b) {
- copy(dst, b[i*8:(i+1)*8])
- dst = dst[8:]
- }
- }
- }
- if len(dst) != 0 {
- panic("dst math")
- }
-
- // Sweep up pair of columns,
- // then down, assigning to right then left pixel.
- // Repeat.
- // See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm
- siz := len(p.Pixel)
- rem := make([]Pixel, 7)
- for i := range rem {
- rem[i] = Extra.Pixel()
- }
- src := append(bits, rem...)
- for x := siz; x > 0; {
- for y := siz - 1; y >= 0; y-- {
- if p.Pixel[y][x-1].Role() == 0 {
- p.Pixel[y][x-1], src = src[0], src[1:]
- }
- if p.Pixel[y][x-2].Role() == 0 {
- p.Pixel[y][x-2], src = src[0], src[1:]
- }
- }
- x -= 2
- if x == 7 { // vertical timing strip
- x--
- }
- for y := 0; y < siz; y++ {
- if p.Pixel[y][x-1].Role() == 0 {
- p.Pixel[y][x-1], src = src[0], src[1:]
- }
- if p.Pixel[y][x-2].Role() == 0 {
- p.Pixel[y][x-2], src = src[0], src[1:]
- }
- }
- x -= 2
- }
- return nil
-}
-
-// mplan edits a version+level-only Plan to add the mask.
-func mplan(m Mask, p *Plan) error {
- p.Mask = m
- for y, row := range p.Pixel {
- for x, pix := range row {
- if r := pix.Role(); (r == Data || r == Check || r == Extra) && p.Mask.Invert(y, x) {
- row[x] ^= Black | Invert
- }
- }
- }
- return nil
-}
-
-// posBox draws a position (large) box at upper left x, y.
-func posBox(m [][]Pixel, x, y int) {
- pos := Position.Pixel()
- // box
- for dy := 0; dy < 7; dy++ {
- for dx := 0; dx < 7; dx++ {
- p := pos
- if dx == 0 || dx == 6 || dy == 0 || dy == 6 || 2 <= dx && dx <= 4 && 2 <= dy && dy <= 4 {
- p |= Black
- }
- m[y+dy][x+dx] = p
- }
- }
- // white border
- for dy := -1; dy < 8; dy++ {
- if 0 <= y+dy && y+dy < len(m) {
- if x > 0 {
- m[y+dy][x-1] = pos
- }
- if x+7 < len(m) {
- m[y+dy][x+7] = pos
- }
- }
- }
- for dx := -1; dx < 8; dx++ {
- if 0 <= x+dx && x+dx < len(m) {
- if y > 0 {
- m[y-1][x+dx] = pos
- }
- if y+7 < len(m) {
- m[y+7][x+dx] = pos
- }
- }
- }
-}
-
-// alignBox draw an alignment (small) box at upper left x, y.
-func alignBox(m [][]Pixel, x, y int) {
- // box
- align := Alignment.Pixel()
- for dy := 0; dy < 5; dy++ {
- for dx := 0; dx < 5; dx++ {
- p := align
- if dx == 0 || dx == 4 || dy == 0 || dy == 4 || dx == 2 && dy == 2 {
- p |= Black
- }
- m[y+dy][x+dx] = p
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr_test.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr_test.go
deleted file mode 100644
index b8199bb51..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package coding
-
-import (
- "bytes"
- "testing"
-
- "github.com/mattermost/rsc/gf256"
- "github.com/mattermost/rsc/qr/libqrencode"
-)
-
-func test(t *testing.T, v Version, l Level, text ...Encoding) bool {
- s := ""
- ty := libqrencode.EightBit
- switch x := text[0].(type) {
- case String:
- s = string(x)
- case Alpha:
- s = string(x)
- ty = libqrencode.Alphanumeric
- case Num:
- s = string(x)
- ty = libqrencode.Numeric
- }
- key, err := libqrencode.Encode(libqrencode.Version(v), libqrencode.Level(l), ty, s)
- if err != nil {
- t.Errorf("libqrencode.Encode(%v, %v, %d, %#q): %v", v, l, ty, s, err)
- return false
- }
- mask := (^key.Pixel[8][2]&1)<<2 | (key.Pixel[8][3]&1)<<1 | (^key.Pixel[8][4] & 1)
- p, err := NewPlan(v, l, Mask(mask))
- if err != nil {
- t.Errorf("NewPlan(%v, L, %d): %v", v, err, mask)
- return false
- }
- if len(p.Pixel) != len(key.Pixel) {
- t.Errorf("%v: NewPlan uses %dx%d, libqrencode uses %dx%d", v, len(p.Pixel), len(p.Pixel), len(key.Pixel), len(key.Pixel))
- return false
- }
- c, err := p.Encode(text...)
- if err != nil {
- t.Errorf("Encode: %v", err)
- return false
- }
- badpix := 0
-Pixel:
- for y, prow := range p.Pixel {
- for x, pix := range prow {
- pix &^= Black
- if c.Black(x, y) {
- pix |= Black
- }
-
- keypix := key.Pixel[y][x]
- want := Pixel(0)
- switch {
- case keypix&libqrencode.Finder != 0:
- want = Position.Pixel()
- case keypix&libqrencode.Alignment != 0:
- want = Alignment.Pixel()
- case keypix&libqrencode.Timing != 0:
- want = Timing.Pixel()
- case keypix&libqrencode.Format != 0:
- want = Format.Pixel()
- want |= OffsetPixel(pix.Offset()) // sic
- want |= pix & Invert
- case keypix&libqrencode.PVersion != 0:
- want = PVersion.Pixel()
- case keypix&libqrencode.DataECC != 0:
- if pix.Role() == Check || pix.Role() == Extra {
- want = pix.Role().Pixel()
- } else {
- want = Data.Pixel()
- }
- want |= OffsetPixel(pix.Offset())
- want |= pix & Invert
- default:
- want = Unused.Pixel()
- }
- if keypix&libqrencode.Black != 0 {
- want |= Black
- }
- if pix != want {
- t.Errorf("%v/%v: Pixel[%d][%d] = %v, want %v %#x", v, mask, y, x, pix, want, keypix)
- if badpix++; badpix >= 100 {
- t.Errorf("stopping after %d bad pixels", badpix)
- break Pixel
- }
- }
- }
- }
- return badpix == 0
-}
-
-var input = []Encoding{
- String("hello"),
- Num("1"),
- Num("12"),
- Num("123"),
- Alpha("AB"),
- Alpha("ABC"),
-}
-
-func TestVersion(t *testing.T) {
- badvers := 0
-Version:
- for v := Version(1); v <= 40; v++ {
- for l := L; l <= H; l++ {
- for _, in := range input {
- if !test(t, v, l, in) {
- if badvers++; badvers >= 10 {
- t.Errorf("stopping after %d bad versions", badvers)
- break Version
- }
- }
- }
- }
- }
-}
-
-func TestEncode(t *testing.T) {
- data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
- check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
- rs := gf256.NewRSEncoder(Field, len(check))
- out := make([]byte, len(check))
- rs.ECC(data, out)
- if !bytes.Equal(out, check) {
- t.Errorf("have %x want %x", out, check)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/Makefile b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/Makefile
deleted file mode 100644
index 4c9591462..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(GOROOT)/src/Make.inc
-TARG=rsc.googlecode.com/hg/qr/libqrencode
-CGOFILES=qrencode.go
-include $(GOROOT)/src/Make.pkg
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/qrencode.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/qrencode.go
deleted file mode 100644
index f4ce3ffb6..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/libqrencode/qrencode.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package libqrencode wraps the C libqrencode library.
-// The qr package (in this package's parent directory)
-// does not use any C wrapping. This code is here only
-// for use during that package's tests.
-package libqrencode
-
-/*
-#cgo LDFLAGS: -lqrencode
-#include <qrencode.h>
-*/
-import "C"
-
-import (
- "fmt"
- "image"
- "image/color"
- "unsafe"
-)
-
-type Version int
-
-type Mode int
-
-const (
- Numeric Mode = C.QR_MODE_NUM
- Alphanumeric Mode = C.QR_MODE_AN
- EightBit Mode = C.QR_MODE_8
-)
-
-type Level int
-
-const (
- L Level = C.QR_ECLEVEL_L
- M Level = C.QR_ECLEVEL_M
- Q Level = C.QR_ECLEVEL_Q
- H Level = C.QR_ECLEVEL_H
-)
-
-type Pixel int
-
-const (
- Black Pixel = 1 << iota
- DataECC
- Format
- PVersion
- Timing
- Alignment
- Finder
- NonData
-)
-
-type Code struct {
- Version int
- Width int
- Pixel [][]Pixel
- Scale int
-}
-
-func (*Code) ColorModel() color.Model {
- return color.RGBAModel
-}
-
-func (c *Code) Bounds() image.Rectangle {
- d := (c.Width + 8) * c.Scale
- return image.Rect(0, 0, d, d)
-}
-
-var (
- white color.Color = color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}
- black color.Color = color.RGBA{0x00, 0x00, 0x00, 0xFF}
- blue color.Color = color.RGBA{0x00, 0x00, 0x80, 0xFF}
- red color.Color = color.RGBA{0xFF, 0x40, 0x40, 0xFF}
- yellow color.Color = color.RGBA{0xFF, 0xFF, 0x00, 0xFF}
- gray color.Color = color.RGBA{0x80, 0x80, 0x80, 0xFF}
- green color.Color = color.RGBA{0x22, 0x8B, 0x22, 0xFF}
-)
-
-func (c *Code) At(x, y int) color.Color {
- x = x/c.Scale - 4
- y = y/c.Scale - 4
- if 0 <= x && x < c.Width && 0 <= y && y < c.Width {
- switch p := c.Pixel[y][x]; {
- case p&Black == 0:
- // nothing
- case p&DataECC != 0:
- return black
- case p&Format != 0:
- return blue
- case p&PVersion != 0:
- return red
- case p&Timing != 0:
- return yellow
- case p&Alignment != 0:
- return gray
- case p&Finder != 0:
- return green
- }
- }
- return white
-}
-
-type Chunk struct {
- Mode Mode
- Text string
-}
-
-func Encode(version Version, level Level, mode Mode, text string) (*Code, error) {
- return EncodeChunk(version, level, Chunk{mode, text})
-}
-
-func EncodeChunk(version Version, level Level, chunk ...Chunk) (*Code, error) {
- qi, err := C.QRinput_new2(C.int(version), C.QRecLevel(level))
- if qi == nil {
- return nil, fmt.Errorf("QRinput_new2: %v", err)
- }
- defer C.QRinput_free(qi)
- for _, ch := range chunk {
- data := []byte(ch.Text)
- n, err := C.QRinput_append(qi, C.QRencodeMode(ch.Mode), C.int(len(data)), (*C.uchar)(&data[0]))
- if n < 0 {
- return nil, fmt.Errorf("QRinput_append %q: %v", data, err)
- }
- }
-
- qc, err := C.QRcode_encodeInput(qi)
- if qc == nil {
- return nil, fmt.Errorf("QRinput_encodeInput: %v", err)
- }
-
- c := &Code{
- Version: int(qc.version),
- Width: int(qc.width),
- Scale: 16,
- }
- pix := make([]Pixel, c.Width*c.Width)
- cdat := (*[1000 * 1000]byte)(unsafe.Pointer(qc.data))[:len(pix)]
- for i := range pix {
- pix[i] = Pixel(cdat[i])
- }
- c.Pixel = make([][]Pixel, c.Width)
- for i := range c.Pixel {
- c.Pixel[i] = pix[i*c.Width : (i+1)*c.Width]
- }
- return c, nil
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go
deleted file mode 100644
index db49d0577..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package qr
-
-// PNG writer for QR codes.
-
-import (
- "bytes"
- "encoding/binary"
- "hash"
- "hash/crc32"
-)
-
-// PNG returns a PNG image displaying the code.
-//
-// PNG uses a custom encoder tailored to QR codes.
-// Its compressed size is about 2x away from optimal,
-// but it runs about 20x faster than calling png.Encode
-// on c.Image().
-func (c *Code) PNG() []byte {
- var p pngWriter
- return p.encode(c)
-}
-
-type pngWriter struct {
- tmp [16]byte
- wctmp [4]byte
- buf bytes.Buffer
- zlib bitWriter
- crc hash.Hash32
-}
-
-var pngHeader = []byte("\x89PNG\r\n\x1a\n")
-
-func (w *pngWriter) encode(c *Code) []byte {
- scale := c.Scale
- siz := c.Size
-
- w.buf.Reset()
-
- // Header
- w.buf.Write(pngHeader)
-
- // Header block
- binary.BigEndian.PutUint32(w.tmp[0:4], uint32((siz+8)*scale))
- binary.BigEndian.PutUint32(w.tmp[4:8], uint32((siz+8)*scale))
- w.tmp[8] = 1 // 1-bit
- w.tmp[9] = 0 // gray
- w.tmp[10] = 0
- w.tmp[11] = 0
- w.tmp[12] = 0
- w.writeChunk("IHDR", w.tmp[:13])
-
- // Comment
- w.writeChunk("tEXt", comment)
-
- // Data
- w.zlib.writeCode(c)
- w.writeChunk("IDAT", w.zlib.bytes.Bytes())
-
- // End
- w.writeChunk("IEND", nil)
-
- return w.buf.Bytes()
-}
-
-var comment = []byte("Software\x00QR-PNG http://qr.swtch.com/")
-
-func (w *pngWriter) writeChunk(name string, data []byte) {
- if w.crc == nil {
- w.crc = crc32.NewIEEE()
- }
- binary.BigEndian.PutUint32(w.wctmp[0:4], uint32(len(data)))
- w.buf.Write(w.wctmp[0:4])
- w.crc.Reset()
- copy(w.wctmp[0:4], name)
- w.buf.Write(w.wctmp[0:4])
- w.crc.Write(w.wctmp[0:4])
- w.buf.Write(data)
- w.crc.Write(data)
- crc := w.crc.Sum32()
- binary.BigEndian.PutUint32(w.wctmp[0:4], crc)
- w.buf.Write(w.wctmp[0:4])
-}
-
-func (b *bitWriter) writeCode(c *Code) {
- const ftNone = 0
-
- b.adler32.Reset()
- b.bytes.Reset()
- b.nbit = 0
-
- scale := c.Scale
- siz := c.Size
-
- // zlib header
- b.tmp[0] = 0x78
- b.tmp[1] = 0
- b.tmp[1] += uint8(31 - (uint16(b.tmp[0])<<8+uint16(b.tmp[1]))%31)
- b.bytes.Write(b.tmp[0:2])
-
- // Start flate block.
- b.writeBits(1, 1, false) // final block
- b.writeBits(1, 2, false) // compressed, fixed Huffman tables
-
- // White border.
- // First row.
- b.byte(ftNone)
- n := (scale*(siz+8) + 7) / 8
- b.byte(255)
- b.repeat(n-1, 1)
- // 4*scale rows total.
- b.repeat((4*scale-1)*(1+n), 1+n)
-
- for i := 0; i < 4*scale; i++ {
- b.adler32.WriteNByte(ftNone, 1)
- b.adler32.WriteNByte(255, n)
- }
-
- row := make([]byte, 1+n)
- for y := 0; y < siz; y++ {
- row[0] = ftNone
- j := 1
- var z uint8
- nz := 0
- for x := -4; x < siz+4; x++ {
- // Raw data.
- for i := 0; i < scale; i++ {
- z <<= 1
- if !c.Black(x, y) {
- z |= 1
- }
- if nz++; nz == 8 {
- row[j] = z
- j++
- nz = 0
- }
- }
- }
- if j < len(row) {
- row[j] = z
- }
- for _, z := range row {
- b.byte(z)
- }
-
- // Scale-1 copies.
- b.repeat((scale-1)*(1+n), 1+n)
-
- b.adler32.WriteN(row, scale)
- }
-
- // White border.
- // First row.
- b.byte(ftNone)
- b.byte(255)
- b.repeat(n-1, 1)
- // 4*scale rows total.
- b.repeat((4*scale-1)*(1+n), 1+n)
-
- for i := 0; i < 4*scale; i++ {
- b.adler32.WriteNByte(ftNone, 1)
- b.adler32.WriteNByte(255, n)
- }
-
- // End of block.
- b.hcode(256)
- b.flushBits()
-
- // adler32
- binary.BigEndian.PutUint32(b.tmp[0:], b.adler32.Sum32())
- b.bytes.Write(b.tmp[0:4])
-}
-
-// A bitWriter is a write buffer for bit-oriented data like deflate.
-type bitWriter struct {
- bytes bytes.Buffer
- bit uint32
- nbit uint
-
- tmp [4]byte
- adler32 adigest
-}
-
-func (b *bitWriter) writeBits(bit uint32, nbit uint, rev bool) {
- // reverse, for huffman codes
- if rev {
- br := uint32(0)
- for i := uint(0); i < nbit; i++ {
- br |= ((bit >> i) & 1) << (nbit - 1 - i)
- }
- bit = br
- }
- b.bit |= bit << b.nbit
- b.nbit += nbit
- for b.nbit >= 8 {
- b.bytes.WriteByte(byte(b.bit))
- b.bit >>= 8
- b.nbit -= 8
- }
-}
-
-func (b *bitWriter) flushBits() {
- if b.nbit > 0 {
- b.bytes.WriteByte(byte(b.bit))
- b.nbit = 0
- b.bit = 0
- }
-}
-
-func (b *bitWriter) hcode(v int) {
- /*
- Lit Value Bits Codes
- --------- ---- -----
- 0 - 143 8 00110000 through
- 10111111
- 144 - 255 9 110010000 through
- 111111111
- 256 - 279 7 0000000 through
- 0010111
- 280 - 287 8 11000000 through
- 11000111
- */
- switch {
- case v <= 143:
- b.writeBits(uint32(v)+0x30, 8, true)
- case v <= 255:
- b.writeBits(uint32(v-144)+0x190, 9, true)
- case v <= 279:
- b.writeBits(uint32(v-256)+0, 7, true)
- case v <= 287:
- b.writeBits(uint32(v-280)+0xc0, 8, true)
- default:
- panic("invalid hcode")
- }
-}
-
-func (b *bitWriter) byte(x byte) {
- b.hcode(int(x))
-}
-
-func (b *bitWriter) codex(c int, val int, nx uint) {
- b.hcode(c + val>>nx)
- b.writeBits(uint32(val)&(1<<nx-1), nx, false)
-}
-
-func (b *bitWriter) repeat(n, d int) {
- for ; n >= 258+3; n -= 258 {
- b.repeat1(258, d)
- }
- if n > 258 {
- // 258 < n < 258+3
- b.repeat1(10, d)
- b.repeat1(n-10, d)
- return
- }
- if n < 3 {
- panic("invalid flate repeat")
- }
- b.repeat1(n, d)
-}
-
-func (b *bitWriter) repeat1(n, d int) {
- /*
- Extra Extra Extra
- Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
- ---- ---- ------ ---- ---- ------- ---- ---- -------
- 257 0 3 267 1 15,16 277 4 67-82
- 258 0 4 268 1 17,18 278 4 83-98
- 259 0 5 269 2 19-22 279 4 99-114
- 260 0 6 270 2 23-26 280 4 115-130
- 261 0 7 271 2 27-30 281 5 131-162
- 262 0 8 272 2 31-34 282 5 163-194
- 263 0 9 273 3 35-42 283 5 195-226
- 264 0 10 274 3 43-50 284 5 227-257
- 265 1 11,12 275 3 51-58 285 0 258
- 266 1 13,14 276 3 59-66
- */
- switch {
- case n <= 10:
- b.codex(257, n-3, 0)
- case n <= 18:
- b.codex(265, n-11, 1)
- case n <= 34:
- b.codex(269, n-19, 2)
- case n <= 66:
- b.codex(273, n-35, 3)
- case n <= 130:
- b.codex(277, n-67, 4)
- case n <= 257:
- b.codex(281, n-131, 5)
- case n == 258:
- b.hcode(285)
- default:
- panic("invalid repeat length")
- }
-
- /*
- Extra Extra Extra
- Code Bits Dist Code Bits Dist Code Bits Distance
- ---- ---- ---- ---- ---- ------ ---- ---- --------
- 0 0 1 10 4 33-48 20 9 1025-1536
- 1 0 2 11 4 49-64 21 9 1537-2048
- 2 0 3 12 5 65-96 22 10 2049-3072
- 3 0 4 13 5 97-128 23 10 3073-4096
- 4 1 5,6 14 6 129-192 24 11 4097-6144
- 5 1 7,8 15 6 193-256 25 11 6145-8192
- 6 2 9-12 16 7 257-384 26 12 8193-12288
- 7 2 13-16 17 7 385-512 27 12 12289-16384
- 8 3 17-24 18 8 513-768 28 13 16385-24576
- 9 3 25-32 19 8 769-1024 29 13 24577-32768
- */
- if d <= 4 {
- b.writeBits(uint32(d-1), 5, true)
- } else if d <= 32768 {
- nbit := uint(16)
- for d <= 1<<(nbit-1) {
- nbit--
- }
- v := uint32(d - 1)
- v &^= 1 << (nbit - 1) // top bit is implicit
- code := uint32(2*nbit - 2) // second bit is low bit of code
- code |= v >> (nbit - 2)
- v &^= 1 << (nbit - 2)
- b.writeBits(code, 5, true)
- // rest of bits follow
- b.writeBits(uint32(v), nbit-2, false)
- } else {
- panic("invalid repeat distance")
- }
-}
-
-func (b *bitWriter) run(v byte, n int) {
- if n == 0 {
- return
- }
- b.byte(v)
- if n-1 < 3 {
- for i := 0; i < n-1; i++ {
- b.byte(v)
- }
- } else {
- b.repeat(n-1, 1)
- }
-}
-
-type adigest struct {
- a, b uint32
-}
-
-func (d *adigest) Reset() { d.a, d.b = 1, 0 }
-
-const amod = 65521
-
-func aupdate(a, b uint32, pi byte, n int) (aa, bb uint32) {
- // TODO(rsc): 6g doesn't do magic multiplies for b %= amod,
- // only for b = b%amod.
-
- // invariant: a, b < amod
- if pi == 0 {
- b += uint32(n%amod) * a
- b = b % amod
- return a, b
- }
-
- // n times:
- // a += pi
- // b += a
- // is same as
- // b += n*a + n*(n+1)/2*pi
- // a += n*pi
- m := uint32(n)
- b += (m % amod) * a
- b = b % amod
- b += (m * (m + 1) / 2) % amod * uint32(pi)
- b = b % amod
- a += (m % amod) * uint32(pi)
- a = a % amod
- return a, b
-}
-
-func afinish(a, b uint32) uint32 {
- return b<<16 | a
-}
-
-func (d *adigest) WriteN(p []byte, n int) {
- for i := 0; i < n; i++ {
- for _, pi := range p {
- d.a, d.b = aupdate(d.a, d.b, pi, 1)
- }
- }
-}
-
-func (d *adigest) WriteNByte(pi byte, n int) {
- d.a, d.b = aupdate(d.a, d.b, pi, n)
-}
-
-func (d *adigest) Sum32() uint32 { return afinish(d.a, d.b) }
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png_test.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png_test.go
deleted file mode 100644
index 27a622924..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package qr
-
-import (
- "bytes"
- "image"
- "image/color"
- "image/png"
- "io/ioutil"
- "testing"
-)
-
-func TestPNG(t *testing.T) {
- c, err := Encode("hello, world", L)
- if err != nil {
- t.Fatal(err)
- }
- pngdat := c.PNG()
- if true {
- ioutil.WriteFile("x.png", pngdat, 0666)
- }
- m, err := png.Decode(bytes.NewBuffer(pngdat))
- if err != nil {
- t.Fatal(err)
- }
- gm := m.(*image.Gray)
-
- scale := c.Scale
- siz := c.Size
- nbad := 0
- for y := 0; y < scale*(8+siz); y++ {
- for x := 0; x < scale*(8+siz); x++ {
- v := byte(255)
- if c.Black(x/scale-4, y/scale-4) {
- v = 0
- }
- if gv := gm.At(x, y).(color.Gray).Y; gv != v {
- t.Errorf("%d,%d = %d, want %d", x, y, gv, v)
- if nbad++; nbad >= 20 {
- t.Fatalf("too many bad pixels")
- }
- }
- }
- }
-}
-
-func BenchmarkPNG(b *testing.B) {
- c, err := Encode("0123456789012345678901234567890123456789", L)
- if err != nil {
- panic(err)
- }
- var bytes []byte
- for i := 0; i < b.N; i++ {
- bytes = c.PNG()
- }
- b.SetBytes(int64(len(bytes)))
-}
-
-func BenchmarkImagePNG(b *testing.B) {
- c, err := Encode("0123456789012345678901234567890123456789", L)
- if err != nil {
- panic(err)
- }
- var buf bytes.Buffer
- for i := 0; i < b.N; i++ {
- buf.Reset()
- png.Encode(&buf, c.Image())
- }
- b.SetBytes(int64(buf.Len()))
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/qr.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/qr.go
deleted file mode 100644
index 1d20d02f3..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/qr.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package qr encodes QR codes.
-*/
-package qr
-
-import (
- "errors"
- "image"
- "image/color"
-
- "github.com/mattermost/rsc/qr/coding"
-)
-
-// A Level denotes a QR error correction level.
-// From least to most tolerant of errors, they are L, M, Q, H.
-type Level int
-
-const (
- L Level = iota // 20% redundant
- M // 38% redundant
- Q // 55% redundant
- H // 65% redundant
-)
-
-// Encode returns an encoding of text at the given error correction level.
-func Encode(text string, level Level) (*Code, error) {
- // Pick data encoding, smallest first.
- // We could split the string and use different encodings
- // but that seems like overkill for now.
- var enc coding.Encoding
- switch {
- case coding.Num(text).Check() == nil:
- enc = coding.Num(text)
- case coding.Alpha(text).Check() == nil:
- enc = coding.Alpha(text)
- default:
- enc = coding.String(text)
- }
-
- // Pick size.
- l := coding.Level(level)
- var v coding.Version
- for v = coding.MinVersion; ; v++ {
- if v > coding.MaxVersion {
- return nil, errors.New("text too long to encode as QR")
- }
- if enc.Bits(v) <= v.DataBytes(l)*8 {
- break
- }
- }
-
- // Build and execute plan.
- p, err := coding.NewPlan(v, l, 0)
- if err != nil {
- return nil, err
- }
- cc, err := p.Encode(enc)
- if err != nil {
- return nil, err
- }
-
- // TODO: Pick appropriate mask.
-
- return &Code{cc.Bitmap, cc.Size, cc.Stride, 8}, nil
-}
-
-// A Code is a square pixel grid.
-// It implements image.Image and direct PNG encoding.
-type Code struct {
- Bitmap []byte // 1 is black, 0 is white
- Size int // number of pixels on a side
- Stride int // number of bytes per row
- Scale int // number of image pixels per QR pixel
-}
-
-// Black returns true if the pixel at (x,y) is black.
-func (c *Code) Black(x, y int) bool {
- return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
- c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
-}
-
-// Image returns an Image displaying the code.
-func (c *Code) Image() image.Image {
- return &codeImage{c}
-
-}
-
-// codeImage implements image.Image
-type codeImage struct {
- *Code
-}
-
-var (
- whiteColor color.Color = color.Gray{0xFF}
- blackColor color.Color = color.Gray{0x00}
-)
-
-func (c *codeImage) Bounds() image.Rectangle {
- d := (c.Size + 8) * c.Scale
- return image.Rect(0, 0, d, d)
-}
-
-func (c *codeImage) At(x, y int) color.Color {
- if c.Black(x, y) {
- return blackColor
- }
- return whiteColor
-}
-
-func (c *codeImage) ColorModel() color.Model {
- return color.GrayModel
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/pic.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/pic.go
deleted file mode 100644
index 6baef94d2..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/pic.go
+++ /dev/null
@@ -1,506 +0,0 @@
-package web
-
-import (
- "bytes"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "net/http"
- "strconv"
- "strings"
-
- "code.google.com/p/freetype-go/freetype"
- "github.com/mattermost/rsc/appfs/fs"
- "github.com/mattermost/rsc/qr"
- "github.com/mattermost/rsc/qr/coding"
-)
-
-func makeImage(req *http.Request, caption, font string, pt, size, border, scale int, f func(x, y int) uint32) *image.RGBA {
- d := (size + 2*border) * scale
- csize := 0
- if caption != "" {
- if pt == 0 {
- pt = 11
- }
- csize = pt * 2
- }
- c := image.NewRGBA(image.Rect(0, 0, d, d+csize))
-
- // white
- u := &image.Uniform{C: color.White}
- draw.Draw(c, c.Bounds(), u, image.ZP, draw.Src)
-
- for y := 0; y < size; y++ {
- for x := 0; x < size; x++ {
- r := image.Rect((x+border)*scale, (y+border)*scale, (x+border+1)*scale, (y+border+1)*scale)
- rgba := f(x, y)
- u.C = color.RGBA{byte(rgba >> 24), byte(rgba >> 16), byte(rgba >> 8), byte(rgba)}
- draw.Draw(c, r, u, image.ZP, draw.Src)
- }
- }
-
- if csize != 0 {
- if font == "" {
- font = "data/luxisr.ttf"
- }
- ctxt := fs.NewContext(req)
- dat, _, err := ctxt.Read(font)
- if err != nil {
- panic(err)
- }
- tfont, err := freetype.ParseFont(dat)
- if err != nil {
- panic(err)
- }
- ft := freetype.NewContext()
- ft.SetDst(c)
- ft.SetDPI(100)
- ft.SetFont(tfont)
- ft.SetFontSize(float64(pt))
- ft.SetSrc(image.NewUniform(color.Black))
- ft.SetClip(image.Rect(0, 0, 0, 0))
- wid, err := ft.DrawString(caption, freetype.Pt(0, 0))
- if err != nil {
- panic(err)
- }
- p := freetype.Pt(d, d+3*pt/2)
- p.X -= wid.X
- p.X /= 2
- ft.SetClip(c.Bounds())
- ft.DrawString(caption, p)
- }
-
- return c
-}
-
-func makeFrame(req *http.Request, font string, pt, vers, l, scale, dots int) image.Image {
- lev := coding.Level(l)
- p, err := coding.NewPlan(coding.Version(vers), lev, 0)
- if err != nil {
- panic(err)
- }
-
- nd := p.DataBytes / p.Blocks
- nc := p.CheckBytes / p.Blocks
- extra := p.DataBytes - nd*p.Blocks
-
- cap := fmt.Sprintf("QR v%d, %s", vers, lev)
- if dots > 0 {
- cap = fmt.Sprintf("QR v%d order, from bottom right", vers)
- }
- m := makeImage(req, cap, font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
- pix := p.Pixel[y][x]
- switch pix.Role() {
- case coding.Data:
- if dots > 0 {
- return 0xffffffff
- }
- off := int(pix.Offset() / 8)
- nd := nd
- var i int
- for i = 0; i < p.Blocks; i++ {
- if i == extra {
- nd++
- }
- if off < nd {
- break
- }
- off -= nd
- }
- return blockColors[i%len(blockColors)]
- case coding.Check:
- if dots > 0 {
- return 0xffffffff
- }
- i := (int(pix.Offset()/8) - p.DataBytes) / nc
- return dark(blockColors[i%len(blockColors)])
- }
- if pix&coding.Black != 0 {
- return 0x000000ff
- }
- return 0xffffffff
- })
-
- if dots > 0 {
- b := m.Bounds()
- for y := 0; y <= len(p.Pixel); y++ {
- for x := 0; x < b.Dx(); x++ {
- m.SetRGBA(x, y*scale-(y/len(p.Pixel)), color.RGBA{127, 127, 127, 255})
- }
- }
- for x := 0; x <= len(p.Pixel); x++ {
- for y := 0; y < b.Dx(); y++ {
- m.SetRGBA(x*scale-(x/len(p.Pixel)), y, color.RGBA{127, 127, 127, 255})
- }
- }
- order := make([]image.Point, (p.DataBytes+p.CheckBytes)*8+1)
- for y, row := range p.Pixel {
- for x, pix := range row {
- if r := pix.Role(); r != coding.Data && r != coding.Check {
- continue
- }
- // draw.Draw(m, m.Bounds().Add(image.Pt(x*scale, y*scale)), dot, image.ZP, draw.Over)
- order[pix.Offset()] = image.Point{x*scale + scale/2, y*scale + scale/2}
- }
- }
-
- for mode := 0; mode < 2; mode++ {
- for i, p := range order {
- q := order[i+1]
- if q.X == 0 {
- break
- }
- line(m, p, q, mode)
- }
- }
- }
- return m
-}
-
-func line(m *image.RGBA, p, q image.Point, mode int) {
- x := 0
- y := 0
- dx := q.X - p.X
- dy := q.Y - p.Y
- xsign := +1
- ysign := +1
- if dx < 0 {
- xsign = -1
- dx = -dx
- }
- if dy < 0 {
- ysign = -1
- dy = -dy
- }
- pt := func() {
- switch mode {
- case 0:
- for dx := -2; dx <= 2; dx++ {
- for dy := -2; dy <= 2; dy++ {
- if dy*dx <= -4 || dy*dx >= 4 {
- continue
- }
- m.SetRGBA(p.X+x*xsign+dx, p.Y+y*ysign+dy, color.RGBA{255, 192, 192, 255})
- }
- }
-
- case 1:
- m.SetRGBA(p.X+x*xsign, p.Y+y*ysign, color.RGBA{128, 0, 0, 255})
- }
- }
- if dx > dy {
- for x < dx || y < dy {
- pt()
- x++
- if float64(x)*float64(dy)/float64(dx)-float64(y) > 0.5 {
- y++
- }
- }
- } else {
- for x < dx || y < dy {
- pt()
- y++
- if float64(y)*float64(dx)/float64(dy)-float64(x) > 0.5 {
- x++
- }
- }
- }
- pt()
-}
-
-func pngEncode(c image.Image) []byte {
- var b bytes.Buffer
- png.Encode(&b, c)
- return b.Bytes()
-}
-
-// Frame handles a request for a single QR frame.
-func Frame(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(makeFrame(req, req.FormValue("font"), arg("pt"), v, arg("l"), scale, arg("dots"))))
-}
-
-// Frames handles a request for multiple QR frames.
-func Frames(w http.ResponseWriter, req *http.Request) {
- vs := strings.Split(req.FormValue("v"), ",")
-
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
- font := req.FormValue("font")
- pt := arg("pt")
- dots := arg("dots")
-
- var images []image.Image
- l := arg("l")
- for _, v := range vs {
- l := l
- if i := strings.Index(v, "."); i >= 0 {
- l, _ = strconv.Atoi(v[i+1:])
- v = v[:i]
- }
- vv, _ := strconv.Atoi(v)
- images = append(images, makeFrame(req, font, pt, vv, l, scale, dots))
- }
-
- b := images[len(images)-1].Bounds()
-
- dx := arg("dx")
- if dx == 0 {
- dx = b.Dx()
- }
- x, y := 0, 0
- xmax := 0
- sep := arg("sep")
- if sep == 0 {
- sep = 10
- }
- var points []image.Point
- for i, m := range images {
- if x > 0 {
- x += sep
- }
- if x > 0 && x+m.Bounds().Dx() > dx {
- y += sep + images[i-1].Bounds().Dy()
- x = 0
- }
- points = append(points, image.Point{x, y})
- x += m.Bounds().Dx()
- if x > xmax {
- xmax = x
- }
-
- }
-
- c := image.NewRGBA(image.Rect(0, 0, xmax, y+b.Dy()))
- for i, m := range images {
- draw.Draw(c, c.Bounds().Add(points[i]), m, image.ZP, draw.Src)
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(c))
-}
-
-// Mask handles a request for a single QR mask.
-func Mask(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- m := arg("m")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(makeMask(req, req.FormValue("font"), arg("pt"), v, m, scale)))
-}
-
-// Masks handles a request for multiple QR masks.
-func Masks(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
- font := req.FormValue("font")
- pt := arg("pt")
- var mm []image.Image
- for m := 0; m < 8; m++ {
- mm = append(mm, makeMask(req, font, pt, v, m, scale))
- }
- dx := mm[0].Bounds().Dx()
- dy := mm[0].Bounds().Dy()
-
- sep := arg("sep")
- if sep == 0 {
- sep = 10
- }
- c := image.NewRGBA(image.Rect(0, 0, (dx+sep)*4-sep, (dy+sep)*2-sep))
- for m := 0; m < 8; m++ {
- x := (m % 4) * (dx + sep)
- y := (m / 4) * (dy + sep)
- draw.Draw(c, c.Bounds().Add(image.Pt(x, y)), mm[m], image.ZP, draw.Src)
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(c))
-}
-
-var maskName = []string{
- "(x+y) % 2",
- "y % 2",
- "x % 3",
- "(x+y) % 3",
- "(y/2 + x/3) % 2",
- "xy%2 + xy%3",
- "(xy%2 + xy%3) % 2",
- "(xy%3 + (x+y)%2) % 2",
-}
-
-func makeMask(req *http.Request, font string, pt int, vers, mask, scale int) image.Image {
- p, err := coding.NewPlan(coding.Version(vers), coding.L, coding.Mask(mask))
- if err != nil {
- panic(err)
- }
- m := makeImage(req, maskName[mask], font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
- pix := p.Pixel[y][x]
- switch pix.Role() {
- case coding.Data, coding.Check:
- if pix&coding.Invert != 0 {
- return 0x000000ff
- }
- }
- return 0xffffffff
- })
- return m
-}
-
-var blockColors = []uint32{
- 0x7777ffff,
- 0xffff77ff,
- 0xff7777ff,
- 0x77ffffff,
- 0x1e90ffff,
- 0xffffe0ff,
- 0x8b6969ff,
- 0x77ff77ff,
- 0x9b30ffff,
- 0x00bfffff,
- 0x90e890ff,
- 0xfff68fff,
- 0xffec8bff,
- 0xffa07aff,
- 0xffa54fff,
- 0xeee8aaff,
- 0x98fb98ff,
- 0xbfbfbfff,
- 0x54ff9fff,
- 0xffaeb9ff,
- 0xb23aeeff,
- 0xbbffffff,
- 0x7fffd4ff,
- 0xff7a7aff,
- 0x00007fff,
-}
-
-func dark(x uint32) uint32 {
- r, g, b, a := byte(x>>24), byte(x>>16), byte(x>>8), byte(x)
- r = r/2 + r/4
- g = g/2 + g/4
- b = b/2 + b/4
- return uint32(r)<<24 | uint32(g)<<16 | uint32(b)<<8 | uint32(a)
-}
-
-func clamp(x int) byte {
- if x < 0 {
- return 0
- }
- if x > 255 {
- return 255
- }
- return byte(x)
-}
-
-func max(x, y int) int {
- if x > y {
- return x
- }
- return y
-}
-
-// Arrow handles a request for an arrow pointing in a given direction.
-func Arrow(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- dir := arg("dir")
- size := arg("size")
- if size == 0 {
- size = 50
- }
- del := size / 10
-
- m := image.NewRGBA(image.Rect(0, 0, size, size))
-
- if dir == 4 {
- draw.Draw(m, m.Bounds(), image.Black, image.ZP, draw.Src)
- draw.Draw(m, image.Rect(5, 5, size-5, size-5), image.White, image.ZP, draw.Src)
- }
-
- pt := func(x, y int, c color.RGBA) {
- switch dir {
- case 0:
- m.SetRGBA(x, y, c)
- case 1:
- m.SetRGBA(y, size-1-x, c)
- case 2:
- m.SetRGBA(size-1-x, size-1-y, c)
- case 3:
- m.SetRGBA(size-1-y, x, c)
- }
- }
-
- for y := 0; y < size/2; y++ {
- for x := 0; x < del && x < y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- for x := del; x < y-del; x++ {
- pt(x, y, color.RGBA{128, 128, 255, 255})
- }
- for x := max(y-del, 0); x <= y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- }
- for y := size / 2; y < size; y++ {
- for x := 0; x < del && x < size-1-y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- for x := del; x < size-1-y-del; x++ {
- pt(x, y, color.RGBA{128, 128, 192, 255})
- }
- for x := max(size-1-y-del, 0); x <= size-1-y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(m))
-}
-
-// Encode encodes a string using the given version, level, and mask.
-func Encode(w http.ResponseWriter, req *http.Request) {
- val := func(s string) int {
- v, _ := strconv.Atoi(req.FormValue(s))
- return v
- }
-
- l := coding.Level(val("l"))
- v := coding.Version(val("v"))
- enc := coding.String(req.FormValue("t"))
- m := coding.Mask(val("m"))
-
- p, err := coding.NewPlan(v, l, m)
- if err != nil {
- panic(err)
- }
- cc, err := p.Encode(enc)
- if err != nil {
- panic(err)
- }
-
- c := &qr.Code{Bitmap: cc.Bitmap, Size: cc.Size, Stride: cc.Stride, Scale: 8}
- w.Header().Set("Content-Type", "image/png")
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(c.PNG())
-}
-
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/play.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/play.go
deleted file mode 100644
index 120f50b81..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/play.go
+++ /dev/null
@@ -1,1118 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-QR data layout
-
-qr/
- upload/
- id.png
- id.fix
- flag/
- id
-
-*/
-// TODO: Random seed taken from GET for caching, repeatability.
-// TODO: Flag for abuse button + some kind of dashboard.
-// TODO: +1 button on web page? permalink?
-// TODO: Flag for abuse button on permalinks too?
-// TODO: Make the page prettier.
-// TODO: Cache headers.
-
-package web
-
-import (
- "bytes"
- "crypto/md5"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "html/template"
- "image"
- "image/color"
- _ "image/gif"
- _ "image/jpeg"
- "image/png"
- "io"
- "math/rand"
- "net/http"
- "net/url"
- "os"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/mattermost/rsc/appfs/fs"
- "github.com/mattermost/rsc/gf256"
- "github.com/mattermost/rsc/qr"
- "github.com/mattermost/rsc/qr/coding"
- "github.com/mattermost/rsc/qr/web/resize"
-)
-
-func runTemplate(c *fs.Context, w http.ResponseWriter, name string, data interface{}) {
- t := template.New("main")
-
- main, _, err := c.Read(name)
- if err != nil {
- panic(err)
- }
- style, _, _ := c.Read("style.html")
- main = append(main, style...)
- _, err = t.Parse(string(main))
- if err != nil {
- panic(err)
- }
-
- var buf bytes.Buffer
- if err := t.Execute(&buf, &data); err != nil {
- panic(err)
- }
- w.Write(buf.Bytes())
-}
-
-func isImgName(s string) bool {
- if len(s) != 32 {
- return false
- }
- for i := 0; i < len(s); i++ {
- if '0' <= s[i] && s[i] <= '9' || 'a' <= s[i] && s[i] <= 'f' {
- continue
- }
- return false
- }
- return true
-}
-
-func isTagName(s string) bool {
- if len(s) != 16 {
- return false
- }
- for i := 0; i < len(s); i++ {
- if '0' <= s[i] && s[i] <= '9' || 'a' <= s[i] && s[i] <= 'f' {
- continue
- }
- return false
- }
- return true
-}
-
-// Draw is the handler for drawing a QR code.
-func Draw(w http.ResponseWriter, req *http.Request) {
- ctxt := fs.NewContext(req)
-
- url := req.FormValue("url")
- if url == "" {
- url = "http://swtch.com/qr"
- }
- if req.FormValue("upload") == "1" {
- upload(w, req, url)
- return
- }
-
- t0 := time.Now()
- img := req.FormValue("i")
- if !isImgName(img) {
- img = "pjw"
- }
- if req.FormValue("show") == "png" {
- i := loadSize(ctxt, img, 48)
- var buf bytes.Buffer
- png.Encode(&buf, i)
- w.Write(buf.Bytes())
- return
- }
- if req.FormValue("flag") == "1" {
- flag(w, req, img, ctxt)
- return
- }
- if req.FormValue("x") == "" {
- var data = struct {
- Name string
- URL string
- }{
- Name: img,
- URL: url,
- }
- runTemplate(ctxt, w, "qr/main.html", &data)
- return
- }
-
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- targ := makeTarg(ctxt, img, 17+4*arg("v")+arg("z"))
-
- m := &Image{
- Name: img,
- Dx: arg("x"),
- Dy: arg("y"),
- URL: req.FormValue("u"),
- Version: arg("v"),
- Mask: arg("m"),
- RandControl: arg("r") > 0,
- Dither: arg("i") > 0,
- OnlyDataBits: arg("d") > 0,
- SaveControl: arg("c") > 0,
- Scale: arg("scale"),
- Target: targ,
- Seed: int64(arg("s")),
- Rotation: arg("o"),
- Size: arg("z"),
- }
- if m.Version > 8 {
- m.Version = 8
- }
-
- if m.Scale == 0 {
- if arg("l") > 1 {
- m.Scale = 8
- } else {
- m.Scale = 4
- }
- }
- if m.Version >= 12 && m.Scale >= 4 {
- m.Scale /= 2
- }
-
- if arg("l") == 1 {
- data, err := json.Marshal(m)
- if err != nil {
- panic(err)
- }
- h := md5.New()
- h.Write(data)
- tag := fmt.Sprintf("%x", h.Sum(nil))[:16]
- if err := ctxt.Write("qrsave/"+tag, data); err != nil {
- panic(err)
- }
- http.Redirect(w, req, "/qr/show/" + tag, http.StatusTemporaryRedirect)
- return
- }
-
- if err := m.Encode(req); err != nil {
- fmt.Fprintf(w, "%s\n", err)
- return
- }
-
- var dat []byte
- switch {
- case m.SaveControl:
- dat = m.Control
- default:
- dat = m.Code.PNG()
- }
-
- if arg("l") > 0 {
- w.Header().Set("Content-Type", "image/png")
- w.Write(dat)
- return
- }
-
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- fmt.Fprint(w, "<center><img src=\"data:image/png;base64,")
- io.WriteString(w, base64.StdEncoding.EncodeToString(dat))
- fmt.Fprint(w, "\" /><br>")
- fmt.Fprintf(w, "<form method=\"POST\" action=\"%s&l=1\"><input type=\"submit\" value=\"Save this QR code\"></form>\n", m.Link())
- fmt.Fprintf(w, "</center>\n")
- fmt.Fprintf(w, "<br><center><font size=-1>%v</font></center>\n", time.Now().Sub(t0))
-}
-
-func (m *Image) Small() bool {
- return 8*(17+4*int(m.Version)) < 512
-}
-
-func (m *Image) Link() string {
- s := fmt.Sprint
- b := func(v bool) string {
- if v {
- return "1"
- }
- return "0"
- }
- val := url.Values{
- "i": {m.Name},
- "x": {s(m.Dx)},
- "y": {s(m.Dy)},
- "z": {s(m.Size)},
- "u": {m.URL},
- "v": {s(m.Version)},
- "m": {s(m.Mask)},
- "r": {b(m.RandControl)},
- "t": {b(m.Dither)},
- "d": {b(m.OnlyDataBits)},
- "c": {b(m.SaveControl)},
- "s": {s(m.Seed)},
- }
- return "/qr/draw?" + val.Encode()
-}
-
-// Show is the handler for showing a stored QR code.
-func Show(w http.ResponseWriter, req *http.Request) {
- ctxt := fs.NewContext(req)
- tag := req.URL.Path[len("/qr/show/"):]
- png := strings.HasSuffix(tag, ".png")
- if png {
- tag = tag[:len(tag)-len(".png")]
- }
- if !isTagName(tag) {
- fmt.Fprintf(w, "Sorry, QR code not found\n")
- return
- }
- if req.FormValue("flag") == "1" {
- flag(w, req, tag, ctxt)
- return
- }
- data, _, err := ctxt.Read("qrsave/" + tag)
- if err != nil {
- fmt.Fprintf(w, "Sorry, QR code not found.\n")
- return
- }
-
- var m Image
- if err := json.Unmarshal(data, &m); err != nil {
- panic(err)
- }
- m.Tag = tag
-
- switch req.FormValue("size") {
- case "big":
- m.Scale *= 2
- case "small":
- m.Scale /= 2
- }
-
- if png {
- if err := m.Encode(req); err != nil {
- panic(err)
- return
- }
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(m.Code.PNG())
- return
- }
-
- w.Header().Set("Cache-Control", "public, max-age=300")
- runTemplate(ctxt, w, "qr/permalink.html", &m)
-}
-
-func upload(w http.ResponseWriter, req *http.Request, link string) {
- // Upload of a new image.
- // Copied from Moustachio demo.
- f, _, err := req.FormFile("image")
- if err != nil {
- fmt.Fprintf(w, "You need to select an image to upload.\n")
- return
- }
- defer f.Close()
-
- i, _, err := image.Decode(f)
- if err != nil {
- panic(err)
- }
-
- // Convert image to 128x128 gray+alpha.
- b := i.Bounds()
- const max = 128
- // If it's gigantic, it's more efficient to downsample first
- // and then resize; resizing will smooth out the roughness.
- var i1 *image.RGBA
- if b.Dx() > 4*max || b.Dy() > 4*max {
- w, h := 2*max, 2*max
- if b.Dx() > b.Dy() {
- h = b.Dy() * h / b.Dx()
- } else {
- w = b.Dx() * w / b.Dy()
- }
- i1 = resize.Resample(i, b, w, h)
- } else {
- // "Resample" to same size, just to convert to RGBA.
- i1 = resize.Resample(i, b, b.Dx(), b.Dy())
- }
- b = i1.Bounds()
-
- // Encode to PNG.
- dx, dy := 128, 128
- if b.Dx() > b.Dy() {
- dy = b.Dy() * dx / b.Dx()
- } else {
- dx = b.Dx() * dy / b.Dy()
- }
- i128 := resize.ResizeRGBA(i1, i1.Bounds(), dx, dy)
-
- var buf bytes.Buffer
- if err := png.Encode(&buf, i128); err != nil {
- panic(err)
- }
-
- h := md5.New()
- h.Write(buf.Bytes())
- tag := fmt.Sprintf("%x", h.Sum(nil))[:32]
-
- ctxt := fs.NewContext(req)
- if err := ctxt.Write("qr/upload/"+tag+".png", buf.Bytes()); err != nil {
- panic(err)
- }
-
- // Redirect with new image tag.
- // Redirect to draw with new image tag.
- http.Redirect(w, req, req.URL.Path+"?"+url.Values{"i": {tag}, "url": {link}}.Encode(), 302)
-}
-
-func flag(w http.ResponseWriter, req *http.Request, img string, ctxt *fs.Context) {
- if !isImgName(img) && !isTagName(img) {
- fmt.Fprintf(w, "Invalid image.\n")
- return
- }
- data, _, _ := ctxt.Read("qr/flag/" + img)
- data = append(data, '!')
- ctxt.Write("qr/flag/" + img, data)
-
- fmt.Fprintf(w, "Thank you. The image has been reported.\n")
-}
-
-func loadSize(ctxt *fs.Context, name string, max int) *image.RGBA {
- data, _, err := ctxt.Read("qr/upload/" + name + ".png")
- if err != nil {
- panic(err)
- }
- i, _, err := image.Decode(bytes.NewBuffer(data))
- if err != nil {
- panic(err)
- }
- b := i.Bounds()
- dx, dy := max, max
- if b.Dx() > b.Dy() {
- dy = b.Dy() * dx / b.Dx()
- } else {
- dx = b.Dx() * dy / b.Dy()
- }
- var irgba *image.RGBA
- switch i := i.(type) {
- case *image.RGBA:
- irgba = resize.ResizeRGBA(i, i.Bounds(), dx, dy)
- case *image.NRGBA:
- irgba = resize.ResizeNRGBA(i, i.Bounds(), dx, dy)
- }
- return irgba
-}
-
-func makeTarg(ctxt *fs.Context, name string, max int) [][]int {
- i := loadSize(ctxt, name, max)
- b := i.Bounds()
- dx, dy := b.Dx(), b.Dy()
- targ := make([][]int, dy)
- arr := make([]int, dx*dy)
- for y := 0; y < dy; y++ {
- targ[y], arr = arr[:dx], arr[dx:]
- row := targ[y]
- for x := 0; x < dx; x++ {
- p := i.Pix[y*i.Stride+4*x:]
- r, g, b, a := p[0], p[1], p[2], p[3]
- if a == 0 {
- row[x] = -1
- } else {
- row[x] = int((299*uint32(r) + 587*uint32(g) + 114*uint32(b) + 500) / 1000)
- }
- }
- }
- return targ
-}
-
-type Image struct {
- Name string
- Target [][]int
- Dx int
- Dy int
- URL string
- Tag string
- Version int
- Mask int
- Scale int
- Rotation int
- Size int
-
- // RandControl says to pick the pixels randomly.
- RandControl bool
- Seed int64
-
- // Dither says to dither instead of using threshold pixel layout.
- Dither bool
-
- // OnlyDataBits says to use only data bits, not check bits.
- OnlyDataBits bool
-
- // Code is the final QR code.
- Code *qr.Code
-
- // Control is a PNG showing the pixels that we controlled.
- // Pixels we don't control are grayed out.
- SaveControl bool
- Control []byte
-}
-
-type Pixinfo struct {
- X int
- Y int
- Pix coding.Pixel
- Targ byte
- DTarg int
- Contrast int
- HardZero bool
- Block *BitBlock
- Bit uint
-}
-
-type Pixorder struct {
- Off int
- Priority int
-}
-
-type byPriority []Pixorder
-
-func (x byPriority) Len() int { return len(x) }
-func (x byPriority) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byPriority) Less(i, j int) bool { return x[i].Priority > x[j].Priority }
-
-func (m *Image) target(x, y int) (targ byte, contrast int) {
- tx := x + m.Dx
- ty := y + m.Dy
- if ty < 0 || ty >= len(m.Target) || tx < 0 || tx >= len(m.Target[ty]) {
- return 255, -1
- }
-
- v0 := m.Target[ty][tx]
- if v0 < 0 {
- return 255, -1
- }
- targ = byte(v0)
-
- n := 0
- sum := 0
- sumsq := 0
- const del = 5
- for dy := -del; dy <= del; dy++ {
- for dx := -del; dx <= del; dx++ {
- if 0 <= ty+dy && ty+dy < len(m.Target) && 0 <= tx+dx && tx+dx < len(m.Target[ty+dy]) {
- v := m.Target[ty+dy][tx+dx]
- sum += v
- sumsq += v * v
- n++
- }
- }
- }
-
- avg := sum / n
- contrast = sumsq/n - avg*avg
- return
-}
-
-func (m *Image) rotate(p *coding.Plan, rot int) {
- if rot == 0 {
- return
- }
-
- N := len(p.Pixel)
- pix := make([][]coding.Pixel, N)
- apix := make([]coding.Pixel, N*N)
- for i := range pix {
- pix[i], apix = apix[:N], apix[N:]
- }
-
- switch rot {
- case 0:
- // ok
- case 1:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[x][N-1-y]
- }
- }
- case 2:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[N-1-y][N-1-x]
- }
- }
- case 3:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[N-1-x][y]
- }
- }
- }
-
- p.Pixel = pix
-}
-
-func (m *Image) Encode(req *http.Request) error {
- p, err := coding.NewPlan(coding.Version(m.Version), coding.L, coding.Mask(m.Mask))
- if err != nil {
- return err
- }
-
- m.rotate(p, m.Rotation)
-
- rand := rand.New(rand.NewSource(m.Seed))
-
- // QR parameters.
- nd := p.DataBytes / p.Blocks
- nc := p.CheckBytes / p.Blocks
- extra := p.DataBytes - nd*p.Blocks
- rs := gf256.NewRSEncoder(coding.Field, nc)
-
- // Build information about pixels, indexed by data/check bit number.
- pixByOff := make([]Pixinfo, (p.DataBytes+p.CheckBytes)*8)
- expect := make([][]bool, len(p.Pixel))
- for y, row := range p.Pixel {
- expect[y] = make([]bool, len(row))
- for x, pix := range row {
- targ, contrast := m.target(x, y)
- if m.RandControl && contrast >= 0 {
- contrast = rand.Intn(128) + 64*((x+y)%2) + 64*((x+y)%3%2)
- }
- expect[y][x] = pix&coding.Black != 0
- if r := pix.Role(); r == coding.Data || r == coding.Check {
- pixByOff[pix.Offset()] = Pixinfo{X: x, Y: y, Pix: pix, Targ: targ, Contrast: contrast}
- }
- }
- }
-
-Again:
- // Count fixed initial data bits, prepare template URL.
- url := m.URL + "#"
- var b coding.Bits
- coding.String(url).Encode(&b, p.Version)
- coding.Num("").Encode(&b, p.Version)
- bbit := b.Bits()
- dbit := p.DataBytes*8 - bbit
- if dbit < 0 {
- return fmt.Errorf("cannot encode URL into available bits")
- }
- num := make([]byte, dbit/10*3)
- for i := range num {
- num[i] = '0'
- }
- b.Pad(dbit)
- b.Reset()
- coding.String(url).Encode(&b, p.Version)
- coding.Num(num).Encode(&b, p.Version)
- b.AddCheckBytes(p.Version, p.Level)
- data := b.Bytes()
-
- doff := 0 // data offset
- coff := 0 // checksum offset
- mbit := bbit + dbit/10*10
-
- // Choose pixels.
- bitblocks := make([]*BitBlock, p.Blocks)
- for blocknum := 0; blocknum < p.Blocks; blocknum++ {
- if blocknum == p.Blocks-extra {
- nd++
- }
-
- bdata := data[doff/8 : doff/8+nd]
- cdata := data[p.DataBytes+coff/8 : p.DataBytes+coff/8+nc]
- bb := newBlock(nd, nc, rs, bdata, cdata)
- bitblocks[blocknum] = bb
-
- // Determine which bits in this block we can try to edit.
- lo, hi := 0, nd*8
- if lo < bbit-doff {
- lo = bbit - doff
- if lo > hi {
- lo = hi
- }
- }
- if hi > mbit-doff {
- hi = mbit - doff
- if hi < lo {
- hi = lo
- }
- }
-
- // Preserve [0, lo) and [hi, nd*8).
- for i := 0; i < lo; i++ {
- if !bb.canSet(uint(i), (bdata[i/8]>>uint(7-i&7))&1) {
- return fmt.Errorf("cannot preserve required bits")
- }
- }
- for i := hi; i < nd*8; i++ {
- if !bb.canSet(uint(i), (bdata[i/8]>>uint(7-i&7))&1) {
- return fmt.Errorf("cannot preserve required bits")
- }
- }
-
- // Can edit [lo, hi) and checksum bits to hit target.
- // Determine which ones to try first.
- order := make([]Pixorder, (hi-lo)+nc*8)
- for i := lo; i < hi; i++ {
- order[i-lo].Off = doff + i
- }
- for i := 0; i < nc*8; i++ {
- order[hi-lo+i].Off = p.DataBytes*8 + coff + i
- }
- if m.OnlyDataBits {
- order = order[:hi-lo]
- }
- for i := range order {
- po := &order[i]
- po.Priority = pixByOff[po.Off].Contrast<<8 | rand.Intn(256)
- }
- sort.Sort(byPriority(order))
-
- const mark = false
- for i := range order {
- po := &order[i]
- pinfo := &pixByOff[po.Off]
- bval := pinfo.Targ
- if bval < 128 {
- bval = 1
- } else {
- bval = 0
- }
- pix := pinfo.Pix
- if pix&coding.Invert != 0 {
- bval ^= 1
- }
- if pinfo.HardZero {
- bval = 0
- }
-
- var bi int
- if pix.Role() == coding.Data {
- bi = po.Off - doff
- } else {
- bi = po.Off - p.DataBytes*8 - coff + nd*8
- }
- if bb.canSet(uint(bi), bval) {
- pinfo.Block = bb
- pinfo.Bit = uint(bi)
- if mark {
- p.Pixel[pinfo.Y][pinfo.X] = coding.Black
- }
- } else {
- if pinfo.HardZero {
- panic("hard zero")
- }
- if mark {
- p.Pixel[pinfo.Y][pinfo.X] = 0
- }
- }
- }
- bb.copyOut()
-
- const cheat = false
- for i := 0; i < nd*8; i++ {
- pinfo := &pixByOff[doff+i]
- pix := p.Pixel[pinfo.Y][pinfo.X]
- if bb.B[i/8]&(1<<uint(7-i&7)) != 0 {
- pix ^= coding.Black
- }
- expect[pinfo.Y][pinfo.X] = pix&coding.Black != 0
- if cheat {
- p.Pixel[pinfo.Y][pinfo.X] = pix & coding.Black
- }
- }
- for i := 0; i < nc*8; i++ {
- pinfo := &pixByOff[p.DataBytes*8+coff+i]
- pix := p.Pixel[pinfo.Y][pinfo.X]
- if bb.B[nd+i/8]&(1<<uint(7-i&7)) != 0 {
- pix ^= coding.Black
- }
- expect[pinfo.Y][pinfo.X] = pix&coding.Black != 0
- if cheat {
- p.Pixel[pinfo.Y][pinfo.X] = pix & coding.Black
- }
- }
- doff += nd * 8
- coff += nc * 8
- }
-
- // Pass over all pixels again, dithering.
- if m.Dither {
- for i := range pixByOff {
- pinfo := &pixByOff[i]
- pinfo.DTarg = int(pinfo.Targ)
- }
- for y, row := range p.Pixel {
- for x, pix := range row {
- if pix.Role() != coding.Data && pix.Role() != coding.Check {
- continue
- }
- pinfo := &pixByOff[pix.Offset()]
- if pinfo.Block == nil {
- // did not choose this pixel
- continue
- }
-
- pix := pinfo.Pix
-
- pval := byte(1) // pixel value (black)
- v := 0 // gray value (black)
- targ := pinfo.DTarg
- if targ >= 128 {
- // want white
- pval = 0
- v = 255
- }
-
- bval := pval // bit value
- if pix&coding.Invert != 0 {
- bval ^= 1
- }
- if pinfo.HardZero && bval != 0 {
- bval ^= 1
- pval ^= 1
- v ^= 255
- }
-
- // Set pixel value as we want it.
- pinfo.Block.reset(pinfo.Bit, bval)
-
- _, _ = x, y
-
- err := targ - v
- if x+1 < len(row) {
- addDither(pixByOff, row[x+1], err*7/16)
- }
- if false && y+1 < len(p.Pixel) {
- if x > 0 {
- addDither(pixByOff, p.Pixel[y+1][x-1], err*3/16)
- }
- addDither(pixByOff, p.Pixel[y+1][x], err*5/16)
- if x+1 < len(row) {
- addDither(pixByOff, p.Pixel[y+1][x+1], err*1/16)
- }
- }
- }
- }
-
- for _, bb := range bitblocks {
- bb.copyOut()
- }
- }
-
- noops := 0
- // Copy numbers back out.
- for i := 0; i < dbit/10; i++ {
- // Pull out 10 bits.
- v := 0
- for j := 0; j < 10; j++ {
- bi := uint(bbit + 10*i + j)
- v <<= 1
- v |= int((data[bi/8] >> (7 - bi&7)) & 1)
- }
- // Turn into 3 digits.
- if v >= 1000 {
- // Oops - too many 1 bits.
- // We know the 512, 256, 128, 64, 32 bits are all set.
- // Pick one at random to clear. This will break some
- // checksum bits, but so be it.
- println("oops", i, v)
- pinfo := &pixByOff[bbit+10*i+3] // TODO random
- pinfo.Contrast = 1e9 >> 8
- pinfo.HardZero = true
- noops++
- }
- num[i*3+0] = byte(v/100 + '0')
- num[i*3+1] = byte(v/10%10 + '0')
- num[i*3+2] = byte(v%10 + '0')
- }
- if noops > 0 {
- goto Again
- }
-
- var b1 coding.Bits
- coding.String(url).Encode(&b1, p.Version)
- coding.Num(num).Encode(&b1, p.Version)
- b1.AddCheckBytes(p.Version, p.Level)
- if !bytes.Equal(b.Bytes(), b1.Bytes()) {
- fmt.Printf("mismatch\n%d %x\n%d %x\n", len(b.Bytes()), b.Bytes(), len(b1.Bytes()), b1.Bytes())
- panic("byte mismatch")
- }
-
- cc, err := p.Encode(coding.String(url), coding.Num(num))
- if err != nil {
- return err
- }
-
- if !m.Dither {
- for y, row := range expect {
- for x, pix := range row {
- if cc.Black(x, y) != pix {
- println("mismatch", x, y, p.Pixel[y][x].String())
- }
- }
- }
- }
-
- m.Code = &qr.Code{Bitmap: cc.Bitmap, Size: cc.Size, Stride: cc.Stride, Scale: m.Scale}
-
- if m.SaveControl {
- m.Control = pngEncode(makeImage(req, "", "", 0, cc.Size, 4, m.Scale, func(x, y int) (rgba uint32) {
- pix := p.Pixel[y][x]
- if pix.Role() == coding.Data || pix.Role() == coding.Check {
- pinfo := &pixByOff[pix.Offset()]
- if pinfo.Block != nil {
- if cc.Black(x, y) {
- return 0x000000ff
- }
- return 0xffffffff
- }
- }
- if cc.Black(x, y) {
- return 0x3f3f3fff
- }
- return 0xbfbfbfff
- }))
- }
-
- return nil
-}
-
-func addDither(pixByOff []Pixinfo, pix coding.Pixel, err int) {
- if pix.Role() != coding.Data && pix.Role() != coding.Check {
- return
- }
- pinfo := &pixByOff[pix.Offset()]
- println("add", pinfo.X, pinfo.Y, pinfo.DTarg, err)
- pinfo.DTarg += err
-}
-
-func readTarget(name string) ([][]int, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- m, err := png.Decode(f)
- if err != nil {
- return nil, fmt.Errorf("decode %s: %v", name, err)
- }
- rect := m.Bounds()
- target := make([][]int, rect.Dy())
- for i := range target {
- target[i] = make([]int, rect.Dx())
- }
- for y, row := range target {
- for x := range row {
- a := int(color.RGBAModel.Convert(m.At(x, y)).(color.RGBA).A)
- t := int(color.GrayModel.Convert(m.At(x, y)).(color.Gray).Y)
- if a == 0 {
- t = -1
- }
- row[x] = t
- }
- }
- return target, nil
-}
-
-type BitBlock struct {
- DataBytes int
- CheckBytes int
- B []byte
- M [][]byte
- Tmp []byte
- RS *gf256.RSEncoder
- bdata []byte
- cdata []byte
-}
-
-func newBlock(nd, nc int, rs *gf256.RSEncoder, dat, cdata []byte) *BitBlock {
- b := &BitBlock{
- DataBytes: nd,
- CheckBytes: nc,
- B: make([]byte, nd+nc),
- Tmp: make([]byte, nc),
- RS: rs,
- bdata: dat,
- cdata: cdata,
- }
- copy(b.B, dat)
- rs.ECC(b.B[:nd], b.B[nd:])
- b.check()
- if !bytes.Equal(b.Tmp, cdata) {
- panic("cdata")
- }
-
- b.M = make([][]byte, nd*8)
- for i := range b.M {
- row := make([]byte, nd+nc)
- b.M[i] = row
- for j := range row {
- row[j] = 0
- }
- row[i/8] = 1 << (7 - uint(i%8))
- rs.ECC(row[:nd], row[nd:])
- }
- return b
-}
-
-func (b *BitBlock) check() {
- b.RS.ECC(b.B[:b.DataBytes], b.Tmp)
- if !bytes.Equal(b.B[b.DataBytes:], b.Tmp) {
- fmt.Printf("ecc mismatch\n%x\n%x\n", b.B[b.DataBytes:], b.Tmp)
- panic("mismatch")
- }
-}
-
-func (b *BitBlock) reset(bi uint, bval byte) {
- if (b.B[bi/8]>>(7-bi&7))&1 == bval {
- // already has desired bit
- return
- }
- // rows that have already been set
- m := b.M[len(b.M):cap(b.M)]
- for _, row := range m {
- if row[bi/8]&(1<<(7-bi&7)) != 0 {
- // Found it.
- for j, v := range row {
- b.B[j] ^= v
- }
- return
- }
- }
- panic("reset of unset bit")
-}
-
-func (b *BitBlock) canSet(bi uint, bval byte) bool {
- found := false
- m := b.M
- for j, row := range m {
- if row[bi/8]&(1<<(7-bi&7)) == 0 {
- continue
- }
- if !found {
- found = true
- if j != 0 {
- m[0], m[j] = m[j], m[0]
- }
- continue
- }
- for k := range row {
- row[k] ^= m[0][k]
- }
- }
- if !found {
- return false
- }
-
- targ := m[0]
-
- // Subtract from saved-away rows too.
- for _, row := range m[len(m):cap(m)] {
- if row[bi/8]&(1<<(7-bi&7)) == 0 {
- continue
- }
- for k := range row {
- row[k] ^= targ[k]
- }
- }
-
- // Found a row with bit #bi == 1 and cut that bit from all the others.
- // Apply to data and remove from m.
- if (b.B[bi/8]>>(7-bi&7))&1 != bval {
- for j, v := range targ {
- b.B[j] ^= v
- }
- }
- b.check()
- n := len(m) - 1
- m[0], m[n] = m[n], m[0]
- b.M = m[:n]
-
- for _, row := range b.M {
- if row[bi/8]&(1<<(7-bi&7)) != 0 {
- panic("did not reduce")
- }
- }
-
- return true
-}
-
-func (b *BitBlock) copyOut() {
- b.check()
- copy(b.bdata, b.B[:b.DataBytes])
- copy(b.cdata, b.B[b.DataBytes:])
-}
-
-func showtable(w http.ResponseWriter, b *BitBlock, gray func(int) bool) {
- nd := b.DataBytes
- nc := b.CheckBytes
-
- fmt.Fprintf(w, "<table class='matrix' cellspacing=0 cellpadding=0 border=0>\n")
- line := func() {
- fmt.Fprintf(w, "<tr height=1 bgcolor='#bbbbbb'><td colspan=%d>\n", (nd+nc)*8)
- }
- line()
- dorow := func(row []byte) {
- fmt.Fprintf(w, "<tr>\n")
- for i := 0; i < (nd+nc)*8; i++ {
- fmt.Fprintf(w, "<td")
- v := row[i/8] >> uint(7-i&7) & 1
- if gray(i) {
- fmt.Fprintf(w, " class='gray'")
- }
- fmt.Fprintf(w, ">")
- if v == 1 {
- fmt.Fprintf(w, "1")
- }
- }
- line()
- }
-
- m := b.M[len(b.M):cap(b.M)]
- for i := len(m) - 1; i >= 0; i-- {
- dorow(m[i])
- }
- m = b.M
- for _, row := range b.M {
- dorow(row)
- }
-
- fmt.Fprintf(w, "</table>\n")
-}
-
-func BitsTable(w http.ResponseWriter, req *http.Request) {
- nd := 2
- nc := 2
- fmt.Fprintf(w, `<html>
- <style type='text/css'>
- .matrix {
- font-family: sans-serif;
- font-size: 0.8em;
- }
- table.matrix {
- padding-left: 1em;
- padding-right: 1em;
- padding-top: 1em;
- padding-bottom: 1em;
- }
- .matrix td {
- padding-left: 0.3em;
- padding-right: 0.3em;
- border-left: 2px solid white;
- border-right: 2px solid white;
- text-align: center;
- color: #aaa;
- }
- .matrix td.gray {
- color: black;
- background-color: #ddd;
- }
- </style>
- `)
- rs := gf256.NewRSEncoder(coding.Field, nc)
- dat := make([]byte, nd+nc)
- b := newBlock(nd, nc, rs, dat[:nd], dat[nd:])
- for i := 0; i < nd*8; i++ {
- b.canSet(uint(i), 0)
- }
- showtable(w, b, func(i int) bool { return i < nd*8 })
-
- b = newBlock(nd, nc, rs, dat[:nd], dat[nd:])
- for j := 0; j < (nd+nc)*8; j += 2 {
- b.canSet(uint(j), 0)
- }
- showtable(w, b, func(i int) bool { return i%2 == 0 })
-
-}
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/resize/resize.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/resize/resize.go
deleted file mode 100644
index 02c8b0040..000000000
--- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/web/resize/resize.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package resize
-
-import (
- "image"
- "image/color"
-)
-
-// average convert the sums to averages and returns the result.
-func average(sum []uint64, w, h int, n uint64) *image.RGBA {
- ret := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- index := 4 * (y*w + x)
- pix := ret.Pix[y*ret.Stride+x*4:]
- pix[0] = uint8(sum[index+0] / n)
- pix[1] = uint8(sum[index+1] / n)
- pix[2] = uint8(sum[index+2] / n)
- pix[3] = uint8(sum[index+3] / n)
- }
- }
- return ret
-}
-
-// ResizeRGBA returns a scaled copy of the RGBA image slice r of m.
-// The returned image has width w and height h.
-func ResizeRGBA(m *image.RGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
-}
-
-// ResizeNRGBA returns a scaled copy of the RGBA image slice r of m.
-// The returned image has width w and height h.
-func ResizeNRGBA(m *image.NRGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- r64 = (r64 * a64) / 255
- g64 = (g64 * a64) / 255
- b64 = (b64 * a64) / 255
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
-}
-
-// Resample returns a resampled copy of the image slice r of m.
-// The returned image has width w and height h.
-func Resample(m image.Image, r image.Rectangle, w, h int) *image.RGBA {
- if w < 0 || h < 0 {
- return nil
- }
- if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
- return image.NewRGBA(image.Rect(0, 0, w, h))
- }
- curw, curh := r.Dx(), r.Dy()
- img := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- // Get a source pixel.
- subx := x * curw / w
- suby := y * curh / h
- r32, g32, b32, a32 := m.At(subx, suby).RGBA()
- r := uint8(r32 >> 8)
- g := uint8(g32 >> 8)
- b := uint8(b32 >> 8)
- a := uint8(a32 >> 8)
- img.SetRGBA(x, y, color.RGBA{r, g, b, a})
- }
- }
- return img
-}
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/.travis.yml b/Godeps/_workspace/src/github.com/mssola/user_agent/.travis.yml
deleted file mode 100644
index 33c596acb..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-go:
- - 1.0
- - 1.1
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - tip
-matrix:
- allow_failures:
- - go: tip
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/LICENSE b/Godeps/_workspace/src/github.com/mssola/user_agent/LICENSE
deleted file mode 100644
index 21d3935c5..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2012-2015 Miquel Sabaté Solà
-
-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.
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/README.md b/Godeps/_workspace/src/github.com/mssola/user_agent/README.md
deleted file mode 100644
index 7f0b15aa5..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-
-# UserAgent [![Build Status](https://travis-ci.org/mssola/user_agent.png?branch=master)](https://travis-ci.org/mssola/user_agent) [![GoDoc](https://godoc.org/github.com/mssola/user_agent?status.png)](http://godoc.org/github.com/mssola/user_agent)
-
-
-UserAgent is a Go library that parses HTTP User Agents.
-
-## Usage
-
-~~~ go
-package main
-
-import (
- "fmt"
-
- "github.com/mssola/user_agent"
-)
-
-func main() {
- // The "New" function will create a new UserAgent object and it will parse
- // the given string. If you need to parse more strings, you can re-use
- // this object and call: ua.Parse("another string")
- ua := user_agent.New("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11");
-
- fmt.Printf("%v\n", ua.Mobile()) // => false
- fmt.Printf("%v\n", ua.Bot()) // => false
- fmt.Printf("%v\n", ua.Mozilla()) // => "5.0"
-
- fmt.Printf("%v\n", ua.Platform()) // => "X11"
- fmt.Printf("%v\n", ua.OS()) // => "Linux x86_64"
-
- name, version := ua.Engine()
- fmt.Printf("%v\n", name) // => "AppleWebKit"
- fmt.Printf("%v\n", version) // => "537.11"
-
- name, version = ua.Browser()
- fmt.Printf("%v\n", name) // => "Chrome"
- fmt.Printf("%v\n", version) // => "23.0.1271.97"
-
- // Let's see an example with a bot.
-
- ua.Parse("Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
-
- fmt.Printf("%v\n", ua.Bot()) // => true
-
- name, version = ua.Browser()
- fmt.Printf("%v\n", name) // => Googlebot
- fmt.Printf("%v\n", version) // => 2.1
-}
-~~~
-
-Copyright &copy; 2012-2015 Miquel Sabaté Solà, released under the MIT License.
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/bot.go b/Godeps/_workspace/src/github.com/mssola/user_agent/bot.go
deleted file mode 100644
index df0b6ccda..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/bot.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (C) 2014-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
-// This file is licensed under the MIT license.
-// See the LICENSE file.
-
-package user_agent
-
-import (
- "regexp"
- "strings"
-)
-
-var botFromSiteRegexp = regexp.MustCompile("http://.+\\.\\w+")
-
-// Get the name of the bot from the website that may be in the given comment. If
-// there is no website in the comment, then an empty string is returned.
-func getFromSite(comment []string) string {
- if len(comment) == 0 {
- return ""
- }
-
- // Where we should check the website.
- idx := 2
- if len(comment) < 3 {
- idx = 0
- }
-
- // Pick the site.
- results := botFromSiteRegexp.FindStringSubmatch(comment[idx])
- if len(results) == 1 {
- // If it's a simple comment, just return the name of the site.
- if idx == 0 {
- return results[0]
- }
-
- // This is a large comment, usually the name will be in the previous
- // field of the comment.
- return strings.TrimSpace(comment[1])
- }
- return ""
-}
-
-// Returns true if the info that we currently have corresponds to the Google
-// mobile bot. This function also modifies some attributes in the receiver
-// accordingly.
-func (p *UserAgent) googleBot() bool {
- // This is a hackish way to detect Google's mobile bot.
- if strings.Index(p.ua, "Googlebot") != -1 {
- p.platform = ""
- p.undecided = true
- }
- return p.undecided
-}
-
-// Set the attributes of the receiver as given by the parameters. All the other
-// parameters are set to empty.
-func (p *UserAgent) setSimple(name, version string, bot bool) {
- p.bot = bot
- if !bot {
- p.mozilla = ""
- }
- p.browser.Name = name
- p.browser.Version = version
- p.browser.Engine = ""
- p.browser.EngineVersion = ""
- p.os = ""
- p.localization = ""
-}
-
-// Fix some values for some weird browsers.
-func (p *UserAgent) fixOther(sections []section) {
- if len(sections) > 0 {
- p.browser.Name = sections[0].name
- p.browser.Version = sections[0].version
- p.mozilla = ""
- }
-}
-
-// Check if we're dealing with a bot or with some weird browser. If that is the
-// case, the receiver will be modified accordingly.
-func (p *UserAgent) checkBot(sections []section) {
- // If there's only one element, and it's doesn't have the Mozilla string,
- // check whether this is a bot or not.
- if len(sections) == 1 && sections[0].name != "Mozilla" {
- p.mozilla = ""
-
- // Check whether the name has some suspicious "bot" in his name.
- reg, _ := regexp.Compile("(?i)bot")
- if reg.Match([]byte(sections[0].name)) {
- p.setSimple(sections[0].name, "", true)
- return
- }
-
- // Tough luck, let's try to see if it has a website in his comment.
- if name := getFromSite(sections[0].comment); name != "" {
- // First of all, this is a bot. Moreover, since it doesn't have the
- // Mozilla string, we can assume that the name and the version are
- // the ones from the first section.
- p.setSimple(sections[0].name, sections[0].version, true)
- return
- }
-
- // At this point we are sure that this is not a bot, but some weirdo.
- p.setSimple(sections[0].name, sections[0].version, false)
- } else {
- // Let's iterate over the available comments and check for a website.
- for _, v := range sections {
- if name := getFromSite(v.comment); name != "" {
- // Ok, we've got a bot name.
- results := strings.SplitN(name, "/", 2)
- version := ""
- if len(results) == 2 {
- version = results[1]
- }
- p.setSimple(results[0], version, true)
- return
- }
- }
-
- // We will assume that this is some other weird browser.
- p.fixOther(sections)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/browser.go b/Godeps/_workspace/src/github.com/mssola/user_agent/browser.go
deleted file mode 100644
index a45c8ab7f..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/browser.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
-// This file is licensed under the MIT license.
-// See the LICENSE file.
-
-package user_agent
-
-import (
- "regexp"
- "strings"
-)
-
-var ie11Regexp = regexp.MustCompile("^rv:(.+)$")
-
-// A struct containing all the information that we might be
-// interested from the browser.
-type Browser struct {
- // The name of the browser's engine.
- Engine string
-
- // The version of the browser's engine.
- EngineVersion string
-
- // The name of the browser.
- Name string
-
- // The version of the browser.
- Version string
-}
-
-// Extract all the information that we can get from the User-Agent string
-// about the browser and update the receiver with this information.
-//
-// The function receives just one argument "sections", that contains the
-// sections from the User-Agent string after being parsed.
-func (p *UserAgent) detectBrowser(sections []section) {
- slen := len(sections)
-
- if sections[0].name == "Opera" {
- p.mozilla = ""
- p.browser.Name = "Opera"
- p.browser.Version = sections[0].version
- p.browser.Engine = "Presto"
- if slen > 1 {
- p.browser.EngineVersion = sections[1].version
- }
- } else if slen > 1 {
- engine := sections[1]
- p.browser.Engine = engine.name
- p.browser.EngineVersion = engine.version
- if slen > 2 {
- p.browser.Version = sections[2].version
- if engine.name == "AppleWebKit" {
- switch sections[slen-1].name {
- case "Edge":
- p.browser.Name = "Edge"
- p.browser.Version = sections[slen-1].version
- p.browser.Engine = "EdgeHTML"
- p.browser.EngineVersion = ""
- case "OPR":
- p.browser.Name = "Opera"
- p.browser.Version = sections[slen-1].version
- default:
- if sections[2].name == "Chrome" {
- p.browser.Name = "Chrome"
- } else {
- p.browser.Name = "Safari"
- }
- }
- } else if engine.name == "Gecko" {
- name := sections[2].name
- if name == "MRA" && slen > 4 {
- name = sections[4].name
- p.browser.Version = sections[4].version
- }
- p.browser.Name = name
- } else if engine.name == "like" && sections[2].name == "Gecko" {
- // This is the new user agent from Internet Explorer 11.
- p.browser.Engine = "Trident"
- p.browser.Name = "Internet Explorer"
- for _, c := range sections[0].comment {
- version := ie11Regexp.FindStringSubmatch(c)
- if len(version) > 0 {
- p.browser.Version = version[1]
- return
- }
- }
- p.browser.Version = ""
- }
- }
- } else if slen == 1 && len(sections[0].comment) > 1 {
- comment := sections[0].comment
- if comment[0] == "compatible" && strings.HasPrefix(comment[1], "MSIE") {
- p.browser.Engine = "Trident"
- p.browser.Name = "Internet Explorer"
- // The MSIE version may be reported as the compatibility version.
- // For IE 8 through 10, the Trident token is more accurate.
- // http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx#VerToken
- for _, v := range comment {
- if strings.HasPrefix(v, "Trident/") {
- switch v[8:] {
- case "4.0":
- p.browser.Version = "8.0"
- case "5.0":
- p.browser.Version = "9.0"
- case "6.0":
- p.browser.Version = "10.0"
- }
- break
- }
- }
- // If the Trident token is not provided, fall back to MSIE token.
- if p.browser.Version == "" {
- p.browser.Version = strings.TrimSpace(comment[1][4:])
- }
- }
- }
-}
-
-// Returns two strings. The first string is the name of the engine and the
-// second one is the version of the engine.
-func (p *UserAgent) Engine() (string, string) {
- return p.browser.Engine, p.browser.EngineVersion
-}
-
-// Returns two strings. The first string is the name of the browser and the
-// second one is the version of the browser.
-func (p *UserAgent) Browser() (string, string) {
- return p.browser.Name, p.browser.Version
-}
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/operating_systems.go b/Godeps/_workspace/src/github.com/mssola/user_agent/operating_systems.go
deleted file mode 100644
index 2771b57e2..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/operating_systems.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
-// This file is licensed under the MIT license.
-// See the LICENSE file.
-
-package user_agent
-
-import "strings"
-
-// Normalize the name of the operating system. By now, this just
-// affects to Windows.
-//
-// Returns a string containing the normalized name for the Operating System.
-func normalizeOS(name string) string {
- sp := strings.SplitN(name, " ", 3)
- if len(sp) != 3 {
- return name
- }
-
- switch sp[2] {
- case "5.0":
- return "Windows 2000"
- case "5.01":
- return "Windows 2000, Service Pack 1 (SP1)"
- case "5.1":
- return "Windows XP"
- case "5.2":
- return "Windows XP x64 Edition"
- case "6.0":
- return "Windows Vista"
- case "6.1":
- return "Windows 7"
- case "6.2":
- return "Windows 8"
- case "6.3":
- return "Windows 8.1"
- case "6.4":
- return "Windows 10"
- }
- return name
-}
-
-// Guess the OS, the localization and if this is a mobile device for a
-// Webkit-powered browser.
-//
-// The first argument p is a reference to the current UserAgent and the second
-// argument is a slice of strings containing the comment.
-func webkit(p *UserAgent, comment []string) {
- if p.platform == "webOS" {
- p.browser.Name = p.platform
- p.os = "Palm"
- if len(comment) > 2 {
- p.localization = comment[2]
- }
- p.mobile = true
- } else if p.platform == "Symbian" {
- p.mobile = true
- p.browser.Name = p.platform
- p.os = comment[0]
- } else if p.platform == "Linux" {
- p.mobile = true
- if p.browser.Name == "Safari" {
- p.browser.Name = "Android"
- }
- if len(comment) > 1 {
- if comment[1] == "U" {
- if len(comment) > 2 {
- p.os = comment[2]
- } else {
- p.mobile = false
- p.os = comment[0]
- }
- } else {
- p.os = comment[1]
- }
- }
- if len(comment) > 3 {
- p.localization = comment[3]
- }
- } else if len(comment) > 0 {
- if len(comment) > 3 {
- p.localization = comment[3]
- }
- if strings.HasPrefix(comment[0], "Windows NT") {
- p.os = normalizeOS(comment[0])
- } else if len(comment) < 2 {
- p.localization = comment[0]
- } else if len(comment) < 3 {
- if !p.googleBot() {
- p.os = normalizeOS(comment[1])
- }
- } else {
- p.os = normalizeOS(comment[2])
- }
- if p.platform == "BlackBerry" {
- p.browser.Name = p.platform
- if p.os == "Touch" {
- p.os = p.platform
- }
- }
- }
-}
-
-// Guess the OS, the localization and if this is a mobile device
-// for a Gecko-powered browser.
-//
-// The first argument p is a reference to the current UserAgent and the second
-// argument is a slice of strings containing the comment.
-func gecko(p *UserAgent, comment []string) {
- if len(comment) > 1 {
- if comment[1] == "U" {
- if len(comment) > 2 {
- p.os = normalizeOS(comment[2])
- } else {
- p.os = normalizeOS(comment[1])
- }
- } else {
- if p.platform == "Android" {
- p.mobile = true
- p.platform, p.os = normalizeOS(comment[1]), p.platform
- } else if comment[0] == "Mobile" || comment[0] == "Tablet" {
- p.mobile = true
- p.os = "FirefoxOS"
- } else {
- if p.os == "" {
- p.os = normalizeOS(comment[1])
- }
- }
- }
- if len(comment) > 3 {
- p.localization = comment[3]
- }
- }
-}
-
-// Guess the OS, the localization and if this is a mobile device
-// for Internet Explorer.
-//
-// The first argument p is a reference to the current UserAgent and the second
-// argument is a slice of strings containing the comment.
-func trident(p *UserAgent, comment []string) {
- // Internet Explorer only runs on Windows.
- p.platform = "Windows"
-
- // The OS can be set before to handle a new case in IE11.
- if p.os == "" {
- if len(comment) > 2 {
- p.os = normalizeOS(comment[2])
- } else {
- p.os = "Windows NT 4.0"
- }
- }
-
- // Last but not least, let's detect if it comes from a mobile device.
- for _, v := range comment {
- if strings.HasPrefix(v, "IEMobile") {
- p.mobile = true
- return
- }
- }
-}
-
-// Guess the OS, the localization and if this is a mobile device
-// for Opera.
-//
-// The first argument p is a reference to the current UserAgent and the second
-// argument is a slice of strings containing the comment.
-func opera(p *UserAgent, comment []string) {
- slen := len(comment)
-
- if strings.HasPrefix(comment[0], "Windows") {
- p.platform = "Windows"
- p.os = normalizeOS(comment[0])
- if slen > 2 {
- if slen > 3 && strings.HasPrefix(comment[2], "MRA") {
- p.localization = comment[3]
- } else {
- p.localization = comment[2]
- }
- }
- } else {
- if strings.HasPrefix(comment[0], "Android") {
- p.mobile = true
- }
- p.platform = comment[0]
- if slen > 1 {
- p.os = comment[1]
- if slen > 3 {
- p.localization = comment[3]
- }
- } else {
- p.os = comment[0]
- }
- }
-}
-
-// Given the comment of the first section of the UserAgent string,
-// get the platform.
-func getPlatform(comment []string) string {
- if len(comment) > 0 {
- if comment[0] != "compatible" {
- if strings.HasPrefix(comment[0], "Windows") {
- return "Windows"
- } else if strings.HasPrefix(comment[0], "Symbian") {
- return "Symbian"
- } else if strings.HasPrefix(comment[0], "webOS") {
- return "webOS"
- } else if comment[0] == "BB10" {
- return "BlackBerry"
- }
- return comment[0]
- }
- }
- return ""
-}
-
-// Detect some properties of the OS from the given section.
-func (p *UserAgent) detectOS(s section) {
- if s.name == "Mozilla" {
- // Get the platform here. Be aware that IE11 provides a new format
- // that is not backwards-compatible with previous versions of IE.
- p.platform = getPlatform(s.comment)
- if p.platform == "Windows" && len(s.comment) > 0 {
- p.os = normalizeOS(s.comment[0])
- }
-
- // And finally get the OS depending on the engine.
- switch p.browser.Engine {
- case "":
- p.undecided = true
- case "Gecko":
- gecko(p, s.comment)
- case "AppleWebKit":
- webkit(p, s.comment)
- case "Trident":
- trident(p, s.comment)
- }
- } else if s.name == "Opera" {
- if len(s.comment) > 0 {
- opera(p, s.comment)
- }
- } else {
- // Check whether this is a bot or just a weird browser.
- p.undecided = true
- }
-}
-
-// Returns a string containing the platform..
-func (p *UserAgent) Platform() string {
- return p.platform
-}
-
-// Returns a string containing the name of the Operating System.
-func (p *UserAgent) OS() string {
- return p.os
-}
-
-// Returns a string containing the localization.
-func (p *UserAgent) Localization() string {
- return p.localization
-}
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/user_agent.go b/Godeps/_workspace/src/github.com/mssola/user_agent/user_agent.go
deleted file mode 100644
index df1aa3b78..000000000
--- a/Godeps/_workspace/src/github.com/mssola/user_agent/user_agent.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
-// This file is licensed under the MIT license.
-// See the LICENSE file.
-
-// Package user_agent implements an HTTP User Agent string parser. It defines
-// the type UserAgent that contains all the information from the parsed string.
-// It also implements the Parse function and getters for all the relevant
-// information that has been extracted from a parsed User Agent string.
-package user_agent
-
-import (
- "strings"
-)
-
-// A section contains the name of the product, its version and
-// an optional comment.
-type section struct {
- name string
- version string
- comment []string
-}
-
-// The UserAgent struct contains all the info that can be extracted
-// from the User-Agent string.
-type UserAgent struct {
- ua string
- mozilla string
- platform string
- os string
- localization string
- browser Browser
- bot bool
- mobile bool
- undecided bool
-}
-
-// Read from the given string until the given delimiter or the
-// end of the string have been reached.
-//
-// The first argument is the user agent string being parsed. The second
-// argument is a reference pointing to the current index of the user agent
-// string. The delimiter argument specifies which character is the delimiter
-// and the cat argument determines whether nested '(' should be ignored or not.
-//
-// Returns an array of bytes containing what has been read.
-func readUntil(ua string, index *int, delimiter byte, cat bool) []byte {
- var buffer []byte
-
- i := *index
- catalan := 0
- for ; i < len(ua); i = i + 1 {
- if ua[i] == delimiter {
- if catalan == 0 {
- *index = i + 1
- return buffer
- }
- catalan--
- } else if cat && ua[i] == '(' {
- catalan++
- }
- buffer = append(buffer, ua[i])
- }
- *index = i + 1
- return buffer
-}
-
-// Parse the given product, that is, just a name or a string
-// formatted as Name/Version.
-//
-// It returns two strings. The first string is the name of the product and the
-// second string contains the version of the product.
-func parseProduct(product []byte) (string, string) {
- prod := strings.SplitN(string(product), "/", 2)
- if len(prod) == 2 {
- return prod[0], prod[1]
- }
- return string(product), ""
-}
-
-// Parse a section. A section is typically formatted as follows
-// "Name/Version (comment)". Both, the comment and the version are optional.
-//
-// The first argument is the user agent string being parsed. The second
-// argument is a reference pointing to the current index of the user agent
-// string.
-//
-// Returns a section containing the information that we could extract
-// from the last parsed section.
-func parseSection(ua string, index *int) (s section) {
- buffer := readUntil(ua, index, ' ', false)
-
- s.name, s.version = parseProduct(buffer)
- if *index < len(ua) && ua[*index] == '(' {
- *index++
- buffer = readUntil(ua, index, ')', true)
- s.comment = strings.Split(string(buffer), "; ")
- *index++
- }
- return s
-}
-
-// Initialize the parser.
-func (p *UserAgent) initialize() {
- p.ua = ""
- p.mozilla = ""
- p.platform = ""
- p.os = ""
- p.localization = ""
- p.browser.Engine = ""
- p.browser.EngineVersion = ""
- p.browser.Name = ""
- p.browser.Version = ""
- p.bot = false
- p.mobile = false
- p.undecided = false
-}
-
-// Parse the given User-Agent string and get the resulting UserAgent object.
-//
-// Returns an UserAgent object that has been initialized after parsing
-// the given User-Agent string.
-func New(ua string) *UserAgent {
- o := &UserAgent{}
- o.Parse(ua)
- return o
-}
-
-// Parse the given User-Agent string. After calling this function, the
-// receiver will be setted up with all the information that we've extracted.
-func (p *UserAgent) Parse(ua string) {
- var sections []section
-
- p.initialize()
- p.ua = ua
- for index, limit := 0, len(ua); index < limit; {
- s := parseSection(ua, &index)
- if !p.mobile && s.name == "Mobile" {
- p.mobile = true
- }
- sections = append(sections, s)
- }
-
- if len(sections) > 0 {
- p.mozilla = sections[0].version
-
- p.detectBrowser(sections)
- p.detectOS(sections[0])
-
- if p.undecided {
- p.checkBot(sections)
- }
- }
-}
-
-// Returns the mozilla version (it's how the User Agent string begins:
-// "Mozilla/5.0 ...", unless we're dealing with Opera, of course).
-func (p *UserAgent) Mozilla() string {
- return p.mozilla
-}
-
-// Returns true if it's a bot, false otherwise.
-func (p *UserAgent) Bot() bool {
- return p.bot
-}
-
-// Returns true if it's a mobile device, false otherwise.
-func (p *UserAgent) Mobile() bool {
- return p.mobile
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/LICENSE b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/LICENSE
deleted file mode 100644
index 609cce797..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2014 Nick Snyder https://github.com/nicksnyder
-
-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.
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go
deleted file mode 100644
index e93db95d7..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go
+++ /dev/null
@@ -1,315 +0,0 @@
-// Package bundle manages translations for multiple languages.
-package bundle
-
-import (
- "encoding/json"
- "fmt"
- "gopkg.in/yaml.v2"
- "io/ioutil"
- "reflect"
-
- "path/filepath"
-
- "github.com/nicksnyder/go-i18n/i18n/language"
- "github.com/nicksnyder/go-i18n/i18n/translation"
-)
-
-// TranslateFunc is a copy of i18n.TranslateFunc to avoid a circular dependency.
-type TranslateFunc func(translationID string, args ...interface{}) string
-
-// Bundle stores the translations for multiple languages.
-type Bundle struct {
- // The primary translations for a language tag and translation id.
- translations map[string]map[string]translation.Translation
-
- // Translations that can be used when an exact language match is not possible.
- fallbackTranslations map[string]map[string]translation.Translation
-}
-
-// New returns an empty bundle.
-func New() *Bundle {
- return &Bundle{
- translations: make(map[string]map[string]translation.Translation),
- fallbackTranslations: make(map[string]map[string]translation.Translation),
- }
-}
-
-// MustLoadTranslationFile is similar to LoadTranslationFile
-// except it panics if an error happens.
-func (b *Bundle) MustLoadTranslationFile(filename string) {
- if err := b.LoadTranslationFile(filename); err != nil {
- panic(err)
- }
-}
-
-// LoadTranslationFile loads the translations from filename into memory.
-//
-// The language that the translations are associated with is parsed from the filename (e.g. en-US.json).
-//
-// Generally you should load translation files once during your program's initialization.
-func (b *Bundle) LoadTranslationFile(filename string) error {
- buf, err := ioutil.ReadFile(filename)
- if err != nil {
- return err
- }
- return b.ParseTranslationFileBytes(filename, buf)
-}
-
-// ParseTranslationFileBytes is similar to LoadTranslationFile except it parses the bytes in buf.
-//
-// It is useful for parsing translation files embedded with go-bindata.
-func (b *Bundle) ParseTranslationFileBytes(filename string, buf []byte) error {
- basename := filepath.Base(filename)
- langs := language.Parse(basename)
- switch l := len(langs); {
- case l == 0:
- return fmt.Errorf("no language found in %q", basename)
- case l > 1:
- return fmt.Errorf("multiple languages found in filename %q: %v; expected one", basename, langs)
- }
- translations, err := parseTranslations(filename, buf)
- if err != nil {
- return err
- }
- b.AddTranslation(langs[0], translations...)
- return nil
-}
-
-func parseTranslations(filename string, buf []byte) ([]translation.Translation, error) {
- var unmarshalFunc func([]byte, interface{}) error
- switch format := filepath.Ext(filename); format {
- case ".json":
- unmarshalFunc = json.Unmarshal
- case ".yaml":
- unmarshalFunc = yaml.Unmarshal
- default:
- return nil, fmt.Errorf("unsupported file extension %s", format)
- }
-
- var translationsData []map[string]interface{}
- if len(buf) > 0 {
- if err := unmarshalFunc(buf, &translationsData); err != nil {
- return nil, err
- }
- }
-
- translations := make([]translation.Translation, 0, len(translationsData))
- for i, translationData := range translationsData {
- t, err := translation.NewTranslation(translationData)
- if err != nil {
- return nil, fmt.Errorf("unable to parse translation #%d in %s because %s\n%v", i, filename, err, translationData)
- }
- translations = append(translations, t)
- }
- return translations, nil
-}
-
-// AddTranslation adds translations for a language.
-//
-// It is useful if your translations are in a format not supported by LoadTranslationFile.
-func (b *Bundle) AddTranslation(lang *language.Language, translations ...translation.Translation) {
- if b.translations[lang.Tag] == nil {
- b.translations[lang.Tag] = make(map[string]translation.Translation, len(translations))
- }
- currentTranslations := b.translations[lang.Tag]
- for _, newTranslation := range translations {
- if currentTranslation := currentTranslations[newTranslation.ID()]; currentTranslation != nil {
- currentTranslations[newTranslation.ID()] = currentTranslation.Merge(newTranslation)
- } else {
- currentTranslations[newTranslation.ID()] = newTranslation
- }
- }
-
- // lang can provide translations for less specific language tags.
- for _, tag := range lang.MatchingTags() {
- b.fallbackTranslations[tag] = currentTranslations
- }
-}
-
-// Translations returns all translations in the bundle.
-func (b *Bundle) Translations() map[string]map[string]translation.Translation {
- return b.translations
-}
-
-// LanguageTags returns the tags of all languages that that have been added.
-func (b *Bundle) LanguageTags() []string {
- var tags []string
- for k := range b.translations {
- tags = append(tags, k)
- }
- return tags
-}
-
-// LanguageTranslationIDs returns the ids of all translations that have been added for a given language.
-func (b *Bundle) LanguageTranslationIDs(languageTag string) []string {
- var ids []string
- for id := range b.translations[languageTag] {
- ids = append(ids, id)
- }
- return ids
-}
-
-// MustTfunc is similar to Tfunc except it panics if an error happens.
-func (b *Bundle) MustTfunc(pref string, prefs ...string) TranslateFunc {
- tfunc, err := b.Tfunc(pref, prefs...)
- if err != nil {
- panic(err)
- }
- return tfunc
-}
-
-// MustTfuncAndLanguage is similar to TfuncAndLanguage except it panics if an error happens.
-func (b *Bundle) MustTfuncAndLanguage(pref string, prefs ...string) (TranslateFunc, *language.Language) {
- tfunc, language, err := b.TfuncAndLanguage(pref, prefs...)
- if err != nil {
- panic(err)
- }
- return tfunc, language
-}
-
-// Tfunc is similar to TfuncAndLanguage except is doesn't return the Language.
-func (b *Bundle) Tfunc(pref string, prefs ...string) (TranslateFunc, error) {
- tfunc, _, err := b.TfuncAndLanguage(pref, prefs...)
- return tfunc, err
-}
-
-// TfuncAndLanguage returns a TranslateFunc for the first Language that
-// has a non-zero number of translations in the bundle.
-//
-// The returned Language matches the the first language preference that could be satisfied,
-// but this may not strictly match the language of the translations used to satisfy that preference.
-//
-// For example, the user may request "zh". If there are no translations for "zh" but there are translations
-// for "zh-cn", then the translations for "zh-cn" will be used but the returned Language will be "zh".
-//
-// It can parse languages from Accept-Language headers (RFC 2616),
-// but it assumes weights are monotonically decreasing.
-func (b *Bundle) TfuncAndLanguage(pref string, prefs ...string) (TranslateFunc, *language.Language, error) {
- lang := b.supportedLanguage(pref, prefs...)
- var err error
- if lang == nil {
- err = fmt.Errorf("no supported languages found %#v", append(prefs, pref))
- }
- return func(translationID string, args ...interface{}) string {
- return b.translate(lang, translationID, args...)
- }, lang, err
-}
-
-// supportedLanguage returns the first language which
-// has a non-zero number of translations in the bundle.
-func (b *Bundle) supportedLanguage(pref string, prefs ...string) *language.Language {
- lang := b.translatedLanguage(pref)
- if lang == nil {
- for _, pref := range prefs {
- lang = b.translatedLanguage(pref)
- if lang != nil {
- break
- }
- }
- }
- return lang
-}
-
-func (b *Bundle) translatedLanguage(src string) *language.Language {
- langs := language.Parse(src)
- for _, lang := range langs {
- if len(b.translations[lang.Tag]) > 0 ||
- len(b.fallbackTranslations[lang.Tag]) > 0 {
- return lang
- }
- }
- return nil
-}
-
-func (b *Bundle) translate(lang *language.Language, translationID string, args ...interface{}) string {
- if lang == nil {
- return translationID
- }
-
- translations := b.translations[lang.Tag]
- if translations == nil {
- translations = b.fallbackTranslations[lang.Tag]
- if translations == nil {
- return translationID
- }
- }
-
- translation := translations[translationID]
- if translation == nil {
- return translationID
- }
-
- var data interface{}
- var count interface{}
- if argc := len(args); argc > 0 {
- if isNumber(args[0]) {
- count = args[0]
- if argc > 1 {
- data = args[1]
- }
- } else {
- data = args[0]
- }
- }
-
- if count != nil {
- if data == nil {
- data = map[string]interface{}{"Count": count}
- } else {
- dataMap := toMap(data)
- dataMap["Count"] = count
- data = dataMap
- }
- }
-
- p, _ := lang.Plural(count)
- template := translation.Template(p)
- if template == nil {
- return translationID
- }
-
- s := template.Execute(data)
- if s == "" {
- return translationID
- }
- return s
-}
-
-func isNumber(n interface{}) bool {
- switch n.(type) {
- case int, int8, int16, int32, int64, string:
- return true
- }
- return false
-}
-
-func toMap(input interface{}) map[string]interface{} {
- if data, ok := input.(map[string]interface{}); ok {
- return data
- }
- v := reflect.ValueOf(input)
- switch v.Kind() {
- case reflect.Ptr:
- return toMap(v.Elem().Interface())
- case reflect.Struct:
- return structToMap(v)
- default:
- return nil
- }
-}
-
-// Converts the top level of a struct to a map[string]interface{}.
-// Code inspired by github.com/fatih/structs.
-func structToMap(v reflect.Value) map[string]interface{} {
- out := make(map[string]interface{})
- t := v.Type()
- for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- if field.PkgPath != "" {
- // unexported field. skip.
- continue
- }
- out[field.Name] = v.FieldByName(field.Name).Interface()
- }
- return out
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/i18n.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/i18n.go
deleted file mode 100644
index f96842966..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/i18n.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Package i18n supports string translations with variable substitution and CLDR pluralization.
-// It is intended to be used in conjunction with the goi18n command, although that is not strictly required.
-//
-// Initialization
-//
-// Your Go program should load translations during its initialization.
-// i18n.MustLoadTranslationFile("path/to/fr-FR.all.json")
-// If your translations are in a file format not supported by (Must)?LoadTranslationFile,
-// then you can use the AddTranslation function to manually add translations.
-//
-// Fetching a translation
-//
-// Use Tfunc or MustTfunc to fetch a TranslateFunc that will return the translated string for a specific language.
-// func handleRequest(w http.ResponseWriter, r *http.Request) {
-// cookieLang := r.Cookie("lang")
-// acceptLang := r.Header.Get("Accept-Language")
-// defaultLang = "en-US" // known valid language
-// T, err := i18n.Tfunc(cookieLang, acceptLang, defaultLang)
-// fmt.Println(T("Hello world"))
-// }
-//
-// Usually it is a good idea to identify strings by a generic id rather than the English translation,
-// but the rest of this documentation will continue to use the English translation for readability.
-// T("Hello world") // ok
-// T("programGreeting") // better!
-//
-// Variables
-//
-// TranslateFunc supports strings that have variables using the text/template syntax.
-// T("Hello {{.Person}}", map[string]interface{}{
-// "Person": "Bob",
-// })
-//
-// Pluralization
-//
-// TranslateFunc supports the pluralization of strings using the CLDR pluralization rules defined here:
-// http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
-// T("You have {{.Count}} unread emails.", 2)
-// T("I am {{.Count}} meters tall.", "1.7")
-//
-// Plural strings may also have variables.
-// T("{{.Person}} has {{.Count}} unread emails", 2, map[string]interface{}{
-// "Person": "Bob",
-// })
-//
-// Sentences with multiple plural components can be supported with nesting.
-// T("{{.Person}} has {{.Count}} unread emails in the past {{.Timeframe}}.", 3, map[string]interface{}{
-// "Person": "Bob",
-// "Timeframe": T("{{.Count}} days", 2),
-// })
-//
-// Templates
-//
-// You can use the .Funcs() method of a text/template or html/template to register a TranslateFunc
-// for usage inside of that template.
-package i18n
-
-import (
- "github.com/nicksnyder/go-i18n/i18n/bundle"
- "github.com/nicksnyder/go-i18n/i18n/language"
- "github.com/nicksnyder/go-i18n/i18n/translation"
-)
-
-// TranslateFunc returns the translation of the string identified by translationID.
-//
-// If there is no translation for translationID, then the translationID itself is returned.
-// This makes it easy to identify missing translations in your app.
-//
-// If translationID is a non-plural form, then the first variadic argument may be a map[string]interface{}
-// or struct that contains template data.
-//
-// If translationID is a plural form, then the first variadic argument must be an integer type
-// (int, int8, int16, int32, int64) or a float formatted as a string (e.g. "123.45").
-// The second variadic argument may be a map[string]interface{} or struct that contains template data.
-type TranslateFunc func(translationID string, args ...interface{}) string
-
-// IdentityTfunc returns a TranslateFunc that always returns the translationID passed to it.
-//
-// It is a useful placeholder when parsing a text/template or html/template
-// before the actual Tfunc is available.
-func IdentityTfunc() TranslateFunc {
- return func(translationID string, args ...interface{}) string {
- return translationID
- }
-}
-
-var defaultBundle = bundle.New()
-
-// MustLoadTranslationFile is similar to LoadTranslationFile
-// except it panics if an error happens.
-func MustLoadTranslationFile(filename string) {
- defaultBundle.MustLoadTranslationFile(filename)
-}
-
-// LoadTranslationFile loads the translations from filename into memory.
-//
-// The language that the translations are associated with is parsed from the filename (e.g. en-US.json).
-//
-// Generally you should load translation files once during your program's initialization.
-func LoadTranslationFile(filename string) error {
- return defaultBundle.LoadTranslationFile(filename)
-}
-
-// ParseTranslationFileBytes is similar to LoadTranslationFile except it parses the bytes in buf.
-//
-// It is useful for parsing translation files embedded with go-bindata.
-func ParseTranslationFileBytes(filename string, buf []byte) error {
- return defaultBundle.ParseTranslationFileBytes(filename, buf)
-}
-
-// AddTranslation adds translations for a language.
-//
-// It is useful if your translations are in a format not supported by LoadTranslationFile.
-func AddTranslation(lang *language.Language, translations ...translation.Translation) {
- defaultBundle.AddTranslation(lang, translations...)
-}
-
-// LanguageTags returns the tags of all languages that have been added.
-func LanguageTags() []string {
- return defaultBundle.LanguageTags()
-}
-
-// LanguageTranslationIDs returns the ids of all translations that have been added for a given language.
-func LanguageTranslationIDs(languageTag string) []string {
- return defaultBundle.LanguageTranslationIDs(languageTag)
-}
-
-// MustTfunc is similar to Tfunc except it panics if an error happens.
-func MustTfunc(languageSource string, languageSources ...string) TranslateFunc {
- return TranslateFunc(defaultBundle.MustTfunc(languageSource, languageSources...))
-}
-
-// Tfunc returns a TranslateFunc that will be bound to the first language which
-// has a non-zero number of translations.
-//
-// It can parse languages from Accept-Language headers (RFC 2616).
-func Tfunc(languageSource string, languageSources ...string) (TranslateFunc, error) {
- tfunc, err := defaultBundle.Tfunc(languageSource, languageSources...)
- return TranslateFunc(tfunc), err
-}
-
-// MustTfuncAndLanguage is similar to TfuncAndLanguage except it panics if an error happens.
-func MustTfuncAndLanguage(languageSource string, languageSources ...string) (TranslateFunc, *language.Language) {
- tfunc, lang := defaultBundle.MustTfuncAndLanguage(languageSource, languageSources...)
- return TranslateFunc(tfunc), lang
-}
-
-// TfuncAndLanguage is similar to Tfunc except it also returns the language which TranslateFunc is bound to.
-func TfuncAndLanguage(languageSource string, languageSources ...string) (TranslateFunc, *language.Language, error) {
- tfunc, lang, err := defaultBundle.TfuncAndLanguage(languageSource, languageSources...)
- return TranslateFunc(tfunc), lang, err
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/language.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/language.go
deleted file mode 100644
index 9a155efc5..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/language.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Package language defines languages that implement CLDR pluralization.
-package language
-
-import (
- "fmt"
- "strings"
-)
-
-// Language is a written human language.
-type Language struct {
- // Tag uniquely identifies the language as defined by RFC 5646.
- //
- // Most language tags are a two character language code (ISO 639-1)
- // optionally followed by a dash and a two character country code (ISO 3166-1).
- // (e.g. en, pt-br)
- Tag string
- *PluralSpec
-}
-
-func (l *Language) String() string {
- return l.Tag
-}
-
-// MatchingTags returns the set of language tags that map to this Language.
-// e.g. "zh-hans-cn" yields {"zh", "zh-hans", "zh-hans-cn"}
-// BUG: This should be computed once and stored as a field on Language for efficiency,
-// but this would require changing how Languages are constructed.
-func (l *Language) MatchingTags() []string {
- parts := strings.Split(l.Tag, "-")
- var prefix, matches []string
- for _, part := range parts {
- prefix = append(prefix, part)
- match := strings.Join(prefix, "-")
- matches = append(matches, match)
- }
- return matches
-}
-
-// Parse returns a slice of supported languages found in src or nil if none are found.
-// It can parse language tags and Accept-Language headers.
-func Parse(src string) []*Language {
- var langs []*Language
- start := 0
- for end, chr := range src {
- switch chr {
- case ',', ';', '.':
- tag := strings.TrimSpace(src[start:end])
- if spec := getPluralSpec(tag); spec != nil {
- langs = append(langs, &Language{NormalizeTag(tag), spec})
- }
- start = end + 1
- }
- }
- if start > 0 {
- tag := strings.TrimSpace(src[start:])
- if spec := getPluralSpec(tag); spec != nil {
- langs = append(langs, &Language{NormalizeTag(tag), spec})
- }
- return dedupe(langs)
- }
- if spec := getPluralSpec(src); spec != nil {
- langs = append(langs, &Language{NormalizeTag(src), spec})
- }
- return langs
-}
-
-func dedupe(langs []*Language) []*Language {
- found := make(map[string]struct{}, len(langs))
- deduped := make([]*Language, 0, len(langs))
- for _, lang := range langs {
- if _, ok := found[lang.Tag]; !ok {
- found[lang.Tag] = struct{}{}
- deduped = append(deduped, lang)
- }
- }
- return deduped
-}
-
-// MustParse is similar to Parse except it panics instead of retuning a nil Language.
-func MustParse(src string) []*Language {
- langs := Parse(src)
- if len(langs) == 0 {
- panic(fmt.Errorf("unable to parse language from %q", src))
- }
- return langs
-}
-
-// Add adds support for a new language.
-func Add(l *Language) {
- tag := NormalizeTag(l.Tag)
- pluralSpecs[tag] = l.PluralSpec
-}
-
-// NormalizeTag returns a language tag with all lower-case characters
-// and dashes "-" instead of underscores "_"
-func NormalizeTag(tag string) string {
- tag = strings.ToLower(tag)
- return strings.Replace(tag, "_", "-", -1)
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/operands.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/operands.go
deleted file mode 100644
index 877bcc89d..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/operands.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package language
-
-import (
- "fmt"
- "strconv"
- "strings"
-)
-
-// http://unicode.org/reports/tr35/tr35-numbers.html#Operands
-type operands struct {
- N float64 // absolute value of the source number (integer and decimals)
- I int64 // integer digits of n
- V int64 // number of visible fraction digits in n, with trailing zeros
- W int64 // number of visible fraction digits in n, without trailing zeros
- F int64 // visible fractional digits in n, with trailing zeros
- T int64 // visible fractional digits in n, without trailing zeros
-}
-
-// NmodEqualAny returns true if o represents an integer equal to any of the arguments.
-func (o *operands) NequalsAny(any ...int64) bool {
- for _, i := range any {
- if o.I == i && o.T == 0 {
- return true
- }
- }
- return false
-}
-
-// NmodEqualAny returns true if o represents an integer equal to any of the arguments modulo mod.
-func (o *operands) NmodEqualsAny(mod int64, any ...int64) bool {
- modI := o.I % mod
- for _, i := range any {
- if modI == i && o.T == 0 {
- return true
- }
- }
- return false
-}
-
-// NmodInRange returns true if o represents an integer in the closed interval [from, to].
-func (o *operands) NinRange(from, to int64) bool {
- return o.T == 0 && from <= o.I && o.I <= to
-}
-
-// NmodInRange returns true if o represents an integer in the closed interval [from, to] modulo mod.
-func (o *operands) NmodInRange(mod, from, to int64) bool {
- modI := o.I % mod
- return o.T == 0 && from <= modI && modI <= to
-}
-
-func newOperands(v interface{}) (*operands, error) {
- switch v := v.(type) {
- case int:
- return newOperandsInt64(int64(v)), nil
- case int8:
- return newOperandsInt64(int64(v)), nil
- case int16:
- return newOperandsInt64(int64(v)), nil
- case int32:
- return newOperandsInt64(int64(v)), nil
- case int64:
- return newOperandsInt64(v), nil
- case string:
- return newOperandsString(v)
- case float32, float64:
- return nil, fmt.Errorf("floats should be formatted into a string")
- default:
- return nil, fmt.Errorf("invalid type %T; expected integer or string", v)
- }
-}
-
-func newOperandsInt64(i int64) *operands {
- if i < 0 {
- i = -i
- }
- return &operands{float64(i), i, 0, 0, 0, 0}
-}
-
-func newOperandsString(s string) (*operands, error) {
- if s[0] == '-' {
- s = s[1:]
- }
- n, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, err
- }
- ops := &operands{N: n}
- parts := strings.SplitN(s, ".", 2)
- ops.I, err = strconv.ParseInt(parts[0], 10, 64)
- if err != nil {
- return nil, err
- }
- if len(parts) == 1 {
- return ops, nil
- }
- fraction := parts[1]
- ops.V = int64(len(fraction))
- for i := ops.V - 1; i >= 0; i-- {
- if fraction[i] != '0' {
- ops.W = i + 1
- break
- }
- }
- if ops.V > 0 {
- f, err := strconv.ParseInt(fraction, 10, 0)
- if err != nil {
- return nil, err
- }
- ops.F = f
- }
- if ops.W > 0 {
- t, err := strconv.ParseInt(fraction[:ops.W], 10, 0)
- if err != nil {
- return nil, err
- }
- ops.T = t
- }
- return ops, nil
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/plural.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/plural.go
deleted file mode 100644
index 1f3ea5c69..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/plural.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package language
-
-import (
- "fmt"
-)
-
-// Plural represents a language pluralization form as defined here:
-// http://cldr.unicode.org/index/cldr-spec/plural-rules
-type Plural string
-
-// All defined plural categories.
-const (
- Invalid Plural = "invalid"
- Zero = "zero"
- One = "one"
- Two = "two"
- Few = "few"
- Many = "many"
- Other = "other"
-)
-
-// NewPlural returns src as a Plural
-// or Invalid and a non-nil error if src is not a valid Plural.
-func NewPlural(src string) (Plural, error) {
- switch src {
- case "zero":
- return Zero, nil
- case "one":
- return One, nil
- case "two":
- return Two, nil
- case "few":
- return Few, nil
- case "many":
- return Many, nil
- case "other":
- return Other, nil
- }
- return Invalid, fmt.Errorf("invalid plural category %s", src)
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec.go
deleted file mode 100644
index fc3522682..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package language
-
-import "strings"
-
-// PluralSpec defines the CLDR plural rules for a language.
-// http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
-// http://unicode.org/reports/tr35/tr35-numbers.html#Operands
-type PluralSpec struct {
- Plurals map[Plural]struct{}
- PluralFunc func(*operands) Plural
-}
-
-var pluralSpecs = make(map[string]*PluralSpec)
-
-func normalizePluralSpecID(id string) string {
- id = strings.Replace(id, "_", "-", -1)
- id = strings.ToLower(id)
- return id
-}
-
-func registerPluralSpec(ids []string, ps *PluralSpec) {
- for _, id := range ids {
- id = normalizePluralSpecID(id)
- pluralSpecs[id] = ps
- }
-}
-
-// Plural returns the plural category for number as defined by
-// the language's CLDR plural rules.
-func (ps *PluralSpec) Plural(number interface{}) (Plural, error) {
- ops, err := newOperands(number)
- if err != nil {
- return Invalid, err
- }
- return ps.PluralFunc(ops), nil
-}
-
-// getPluralSpec returns the PluralSpec that matches the longest prefix of tag.
-// It returns nil if no PluralSpec matches tag.
-func getPluralSpec(tag string) *PluralSpec {
- tag = NormalizeTag(tag)
- subtag := tag
- for {
- if spec := pluralSpecs[subtag]; spec != nil {
- return spec
- }
- end := strings.LastIndex(subtag, "-")
- if end == -1 {
- return nil
- }
- subtag = subtag[:end]
- }
-}
-
-func newPluralSet(plurals ...Plural) map[Plural]struct{} {
- set := make(map[Plural]struct{}, len(plurals))
- for _, plural := range plurals {
- set[plural] = struct{}{}
- }
- return set
-}
-
-func intInRange(i, from, to int64) bool {
- return from <= i && i <= to
-}
-
-func intEqualsAny(i int64, any ...int64) bool {
- for _, a := range any {
- if i == a {
- return true
- }
- }
- return false
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec_gen.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec_gen.go
deleted file mode 100644
index c9b4f2667..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/language/pluralspec_gen.go
+++ /dev/null
@@ -1,567 +0,0 @@
-package language
-
-// This file is generated by i18n/language/codegen/generate.sh
-
-func init() {
-
- registerPluralSpec([]string{"bm", "bo", "dz", "id", "ig", "ii", "in", "ja", "jbo", "jv", "jw", "kde", "kea", "km", "ko", "lkt", "lo", "ms", "my", "nqo", "root", "sah", "ses", "sg", "th", "to", "vi", "wo", "yo", "zh"}, &PluralSpec{
- Plurals: newPluralSet(Other),
- PluralFunc: func(ops *operands) Plural {
- return Other
- },
- })
- registerPluralSpec([]string{"am", "as", "bn", "fa", "gu", "hi", "kn", "mr", "zu"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 0 or n = 1
- if intEqualsAny(ops.I, 0) ||
- ops.NequalsAny(1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ff", "fr", "hy", "kab"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 0,1
- if intEqualsAny(ops.I, 0, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ast", "ca", "de", "en", "et", "fi", "fy", "gl", "it", "ji", "nl", "sv", "sw", "ur", "yi"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 1 and v = 0
- if intEqualsAny(ops.I, 1) && intEqualsAny(ops.V, 0) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"si"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0,1 or i = 0 and f = 1
- if ops.NequalsAny(0, 1) ||
- intEqualsAny(ops.I, 0) && intEqualsAny(ops.F, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ak", "bh", "guw", "ln", "mg", "nso", "pa", "ti", "wa"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0..1
- if ops.NinRange(0, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"tzm"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0..1 or n = 11..99
- if ops.NinRange(0, 1) ||
- ops.NinRange(11, 99) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"pt"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0..2 and n != 2
- if ops.NinRange(0, 2) && !ops.NequalsAny(2) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"af", "asa", "az", "bem", "bez", "bg", "brx", "ce", "cgg", "chr", "ckb", "dv", "ee", "el", "eo", "es", "eu", "fo", "fur", "gsw", "ha", "haw", "hu", "jgo", "jmc", "ka", "kaj", "kcg", "kk", "kkj", "kl", "ks", "ksb", "ku", "ky", "lb", "lg", "mas", "mgo", "ml", "mn", "nah", "nb", "nd", "ne", "nn", "nnh", "no", "nr", "ny", "nyn", "om", "or", "os", "pap", "ps", "rm", "rof", "rwk", "saq", "sdh", "seh", "sn", "so", "sq", "ss", "ssy", "st", "syr", "ta", "te", "teo", "tig", "tk", "tn", "tr", "ts", "ug", "uz", "ve", "vo", "vun", "wae", "xh", "xog"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"pt_PT"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1 and v = 0
- if ops.NequalsAny(1) && intEqualsAny(ops.V, 0) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"da"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1 or t != 0 and i = 0,1
- if ops.NequalsAny(1) ||
- !intEqualsAny(ops.T, 0) && intEqualsAny(ops.I, 0, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"is"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // t = 0 and i % 10 = 1 and i % 100 != 11 or t != 0
- if intEqualsAny(ops.T, 0) && intEqualsAny(ops.I%10, 1) && !intEqualsAny(ops.I%100, 11) ||
- !intEqualsAny(ops.T, 0) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"mk"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 10 = 1 or f % 10 = 1
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 1) ||
- intEqualsAny(ops.F%10, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"fil", "tl"}, &PluralSpec{
- Plurals: newPluralSet(One, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I, 1, 2, 3) ||
- intEqualsAny(ops.V, 0) && !intEqualsAny(ops.I%10, 4, 6, 9) ||
- !intEqualsAny(ops.V, 0) && !intEqualsAny(ops.F%10, 4, 6, 9) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"lv", "prg"}, &PluralSpec{
- Plurals: newPluralSet(Zero, One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19
- if ops.NmodEqualsAny(10, 0) ||
- ops.NmodInRange(100, 11, 19) ||
- intEqualsAny(ops.V, 2) && intInRange(ops.F%100, 11, 19) {
- return Zero
- }
- // n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1
- if ops.NmodEqualsAny(10, 1) && !ops.NmodEqualsAny(100, 11) ||
- intEqualsAny(ops.V, 2) && intEqualsAny(ops.F%10, 1) && !intEqualsAny(ops.F%100, 11) ||
- !intEqualsAny(ops.V, 2) && intEqualsAny(ops.F%10, 1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"lag"}, &PluralSpec{
- Plurals: newPluralSet(Zero, One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0
- if ops.NequalsAny(0) {
- return Zero
- }
- // i = 0,1 and n != 0
- if intEqualsAny(ops.I, 0, 1) && !ops.NequalsAny(0) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ksh"}, &PluralSpec{
- Plurals: newPluralSet(Zero, One, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0
- if ops.NequalsAny(0) {
- return Zero
- }
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- return Other
- },
- })
- registerPluralSpec([]string{"iu", "kw", "naq", "se", "sma", "smi", "smj", "smn", "sms"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- // n = 2
- if ops.NequalsAny(2) {
- return Two
- }
- return Other
- },
- })
- registerPluralSpec([]string{"shi"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 0 or n = 1
- if intEqualsAny(ops.I, 0) ||
- ops.NequalsAny(1) {
- return One
- }
- // n = 2..10
- if ops.NinRange(2, 10) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"mo", "ro"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 1 and v = 0
- if intEqualsAny(ops.I, 1) && intEqualsAny(ops.V, 0) {
- return One
- }
- // v != 0 or n = 0 or n != 1 and n % 100 = 1..19
- if !intEqualsAny(ops.V, 0) ||
- ops.NequalsAny(0) ||
- !ops.NequalsAny(1) && ops.NmodInRange(100, 1, 19) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"bs", "hr", "sh", "sr"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 1) && !intEqualsAny(ops.I%100, 11) ||
- intEqualsAny(ops.F%10, 1) && !intEqualsAny(ops.F%100, 11) {
- return One
- }
- // v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14
- if intEqualsAny(ops.V, 0) && intInRange(ops.I%10, 2, 4) && !intInRange(ops.I%100, 12, 14) ||
- intInRange(ops.F%10, 2, 4) && !intInRange(ops.F%100, 12, 14) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"gd"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1,11
- if ops.NequalsAny(1, 11) {
- return One
- }
- // n = 2,12
- if ops.NequalsAny(2, 12) {
- return Two
- }
- // n = 3..10,13..19
- if ops.NinRange(3, 10) || ops.NinRange(13, 19) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"sl"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 100 = 1
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%100, 1) {
- return One
- }
- // v = 0 and i % 100 = 2
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%100, 2) {
- return Two
- }
- // v = 0 and i % 100 = 3..4 or v != 0
- if intEqualsAny(ops.V, 0) && intInRange(ops.I%100, 3, 4) ||
- !intEqualsAny(ops.V, 0) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"dsb", "hsb"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 100 = 1 or f % 100 = 1
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%100, 1) ||
- intEqualsAny(ops.F%100, 1) {
- return One
- }
- // v = 0 and i % 100 = 2 or f % 100 = 2
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%100, 2) ||
- intEqualsAny(ops.F%100, 2) {
- return Two
- }
- // v = 0 and i % 100 = 3..4 or f % 100 = 3..4
- if intEqualsAny(ops.V, 0) && intInRange(ops.I%100, 3, 4) ||
- intInRange(ops.F%100, 3, 4) {
- return Few
- }
- return Other
- },
- })
- registerPluralSpec([]string{"he", "iw"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 1 and v = 0
- if intEqualsAny(ops.I, 1) && intEqualsAny(ops.V, 0) {
- return One
- }
- // i = 2 and v = 0
- if intEqualsAny(ops.I, 2) && intEqualsAny(ops.V, 0) {
- return Two
- }
- // v = 0 and n != 0..10 and n % 10 = 0
- if intEqualsAny(ops.V, 0) && !ops.NinRange(0, 10) && ops.NmodEqualsAny(10, 0) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"cs", "sk"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 1 and v = 0
- if intEqualsAny(ops.I, 1) && intEqualsAny(ops.V, 0) {
- return One
- }
- // i = 2..4 and v = 0
- if intInRange(ops.I, 2, 4) && intEqualsAny(ops.V, 0) {
- return Few
- }
- // v != 0
- if !intEqualsAny(ops.V, 0) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"pl"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // i = 1 and v = 0
- if intEqualsAny(ops.I, 1) && intEqualsAny(ops.V, 0) {
- return One
- }
- // v = 0 and i % 10 = 2..4 and i % 100 != 12..14
- if intEqualsAny(ops.V, 0) && intInRange(ops.I%10, 2, 4) && !intInRange(ops.I%100, 12, 14) {
- return Few
- }
- // v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14
- if intEqualsAny(ops.V, 0) && !intEqualsAny(ops.I, 1) && intInRange(ops.I%10, 0, 1) ||
- intEqualsAny(ops.V, 0) && intInRange(ops.I%10, 5, 9) ||
- intEqualsAny(ops.V, 0) && intInRange(ops.I%100, 12, 14) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"be"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n % 10 = 1 and n % 100 != 11
- if ops.NmodEqualsAny(10, 1) && !ops.NmodEqualsAny(100, 11) {
- return One
- }
- // n % 10 = 2..4 and n % 100 != 12..14
- if ops.NmodInRange(10, 2, 4) && !ops.NmodInRange(100, 12, 14) {
- return Few
- }
- // n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14
- if ops.NmodEqualsAny(10, 0) ||
- ops.NmodInRange(10, 5, 9) ||
- ops.NmodInRange(100, 11, 14) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"lt"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n % 10 = 1 and n % 100 != 11..19
- if ops.NmodEqualsAny(10, 1) && !ops.NmodInRange(100, 11, 19) {
- return One
- }
- // n % 10 = 2..9 and n % 100 != 11..19
- if ops.NmodInRange(10, 2, 9) && !ops.NmodInRange(100, 11, 19) {
- return Few
- }
- // f != 0
- if !intEqualsAny(ops.F, 0) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"mt"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- // n = 0 or n % 100 = 2..10
- if ops.NequalsAny(0) ||
- ops.NmodInRange(100, 2, 10) {
- return Few
- }
- // n % 100 = 11..19
- if ops.NmodInRange(100, 11, 19) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ru", "uk"}, &PluralSpec{
- Plurals: newPluralSet(One, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 10 = 1 and i % 100 != 11
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 1) && !intEqualsAny(ops.I%100, 11) {
- return One
- }
- // v = 0 and i % 10 = 2..4 and i % 100 != 12..14
- if intEqualsAny(ops.V, 0) && intInRange(ops.I%10, 2, 4) && !intInRange(ops.I%100, 12, 14) {
- return Few
- }
- // v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 0) ||
- intEqualsAny(ops.V, 0) && intInRange(ops.I%10, 5, 9) ||
- intEqualsAny(ops.V, 0) && intInRange(ops.I%100, 11, 14) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"br"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n % 10 = 1 and n % 100 != 11,71,91
- if ops.NmodEqualsAny(10, 1) && !ops.NmodEqualsAny(100, 11, 71, 91) {
- return One
- }
- // n % 10 = 2 and n % 100 != 12,72,92
- if ops.NmodEqualsAny(10, 2) && !ops.NmodEqualsAny(100, 12, 72, 92) {
- return Two
- }
- // n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99
- if (ops.NmodInRange(10, 3, 4) || ops.NmodEqualsAny(10, 9)) && !(ops.NmodInRange(100, 10, 19) || ops.NmodInRange(100, 70, 79) || ops.NmodInRange(100, 90, 99)) {
- return Few
- }
- // n != 0 and n % 1000000 = 0
- if !ops.NequalsAny(0) && ops.NmodEqualsAny(1000000, 0) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ga"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- // n = 2
- if ops.NequalsAny(2) {
- return Two
- }
- // n = 3..6
- if ops.NinRange(3, 6) {
- return Few
- }
- // n = 7..10
- if ops.NinRange(7, 10) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"gv"}, &PluralSpec{
- Plurals: newPluralSet(One, Two, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // v = 0 and i % 10 = 1
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 1) {
- return One
- }
- // v = 0 and i % 10 = 2
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%10, 2) {
- return Two
- }
- // v = 0 and i % 100 = 0,20,40,60,80
- if intEqualsAny(ops.V, 0) && intEqualsAny(ops.I%100, 0, 20, 40, 60, 80) {
- return Few
- }
- // v != 0
- if !intEqualsAny(ops.V, 0) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"ar"}, &PluralSpec{
- Plurals: newPluralSet(Zero, One, Two, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0
- if ops.NequalsAny(0) {
- return Zero
- }
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- // n = 2
- if ops.NequalsAny(2) {
- return Two
- }
- // n % 100 = 3..10
- if ops.NmodInRange(100, 3, 10) {
- return Few
- }
- // n % 100 = 11..99
- if ops.NmodInRange(100, 11, 99) {
- return Many
- }
- return Other
- },
- })
- registerPluralSpec([]string{"cy"}, &PluralSpec{
- Plurals: newPluralSet(Zero, One, Two, Few, Many, Other),
- PluralFunc: func(ops *operands) Plural {
- // n = 0
- if ops.NequalsAny(0) {
- return Zero
- }
- // n = 1
- if ops.NequalsAny(1) {
- return One
- }
- // n = 2
- if ops.NequalsAny(2) {
- return Two
- }
- // n = 3
- if ops.NequalsAny(3) {
- return Few
- }
- // n = 6
- if ops.NequalsAny(6) {
- return Many
- }
- return Other
- },
- })
-}
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go
deleted file mode 100644
index 4f579d16a..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package translation
-
-import (
- "github.com/nicksnyder/go-i18n/i18n/language"
-)
-
-type pluralTranslation struct {
- id string
- templates map[language.Plural]*template
-}
-
-func (pt *pluralTranslation) MarshalInterface() interface{} {
- return map[string]interface{}{
- "id": pt.id,
- "translation": pt.templates,
- }
-}
-
-func (pt *pluralTranslation) ID() string {
- return pt.id
-}
-
-func (pt *pluralTranslation) Template(pc language.Plural) *template {
- return pt.templates[pc]
-}
-
-func (pt *pluralTranslation) UntranslatedCopy() Translation {
- return &pluralTranslation{pt.id, make(map[language.Plural]*template)}
-}
-
-func (pt *pluralTranslation) Normalize(l *language.Language) Translation {
- // Delete plural categories that don't belong to this language.
- for pc := range pt.templates {
- if _, ok := l.Plurals[pc]; !ok {
- delete(pt.templates, pc)
- }
- }
- // Create map entries for missing valid categories.
- for pc := range l.Plurals {
- if _, ok := pt.templates[pc]; !ok {
- pt.templates[pc] = mustNewTemplate("")
- }
- }
- return pt
-}
-
-func (pt *pluralTranslation) Backfill(src Translation) Translation {
- for pc, t := range pt.templates {
- if t == nil || t.src == "" {
- pt.templates[pc] = src.Template(language.Other)
- }
- }
- return pt
-}
-
-func (pt *pluralTranslation) Merge(t Translation) Translation {
- other, ok := t.(*pluralTranslation)
- if !ok || pt.ID() != t.ID() {
- return t
- }
- for pluralCategory, template := range other.templates {
- if template != nil && template.src != "" {
- pt.templates[pluralCategory] = template
- }
- }
- return pt
-}
-
-func (pt *pluralTranslation) Incomplete(l *language.Language) bool {
- for pc := range l.Plurals {
- if t := pt.templates[pc]; t == nil || t.src == "" {
- return true
- }
- }
- return false
-}
-
-var _ = Translation(&pluralTranslation{})
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go
deleted file mode 100644
index 1010e5947..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package translation
-
-import (
- "github.com/nicksnyder/go-i18n/i18n/language"
-)
-
-type singleTranslation struct {
- id string
- template *template
-}
-
-func (st *singleTranslation) MarshalInterface() interface{} {
- return map[string]interface{}{
- "id": st.id,
- "translation": st.template,
- }
-}
-
-func (st *singleTranslation) ID() string {
- return st.id
-}
-
-func (st *singleTranslation) Template(pc language.Plural) *template {
- return st.template
-}
-
-func (st *singleTranslation) UntranslatedCopy() Translation {
- return &singleTranslation{st.id, mustNewTemplate("")}
-}
-
-func (st *singleTranslation) Normalize(language *language.Language) Translation {
- return st
-}
-
-func (st *singleTranslation) Backfill(src Translation) Translation {
- if st.template == nil || st.template.src == "" {
- st.template = src.Template(language.Other)
- }
- return st
-}
-
-func (st *singleTranslation) Merge(t Translation) Translation {
- other, ok := t.(*singleTranslation)
- if !ok || st.ID() != t.ID() {
- return t
- }
- if other.template != nil && other.template.src != "" {
- st.template = other.template
- }
- return st
-}
-
-func (st *singleTranslation) Incomplete(l *language.Language) bool {
- return st.template == nil || st.template.src == ""
-}
-
-var _ = Translation(&singleTranslation{})
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/template.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/template.go
deleted file mode 100644
index c8756fa4e..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/template.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package translation
-
-import (
- "bytes"
- "encoding"
- "strings"
- gotemplate "text/template"
-)
-
-type template struct {
- tmpl *gotemplate.Template
- src string
-}
-
-func newTemplate(src string) (*template, error) {
- var tmpl template
- err := tmpl.parseTemplate(src)
- return &tmpl, err
-}
-
-func mustNewTemplate(src string) *template {
- t, err := newTemplate(src)
- if err != nil {
- panic(err)
- }
- return t
-}
-
-func (t *template) String() string {
- return t.src
-}
-
-func (t *template) Execute(args interface{}) string {
- if t.tmpl == nil {
- return t.src
- }
- var buf bytes.Buffer
- if err := t.tmpl.Execute(&buf, args); err != nil {
- return err.Error()
- }
- return buf.String()
-}
-
-func (t *template) MarshalText() ([]byte, error) {
- return []byte(t.src), nil
-}
-
-func (t *template) UnmarshalText(src []byte) error {
- return t.parseTemplate(string(src))
-}
-
-func (t *template) parseTemplate(src string) (err error) {
- t.src = src
- if strings.Contains(src, "{{") {
- t.tmpl, err = gotemplate.New(src).Parse(src)
- }
- return
-}
-
-var _ = encoding.TextMarshaler(&template{})
-var _ = encoding.TextUnmarshaler(&template{})
diff --git a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/translation.go b/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/translation.go
deleted file mode 100644
index fa93180b8..000000000
--- a/Godeps/_workspace/src/github.com/nicksnyder/go-i18n/i18n/translation/translation.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Package translation defines the interface for a translation.
-package translation
-
-import (
- "fmt"
-
- "github.com/nicksnyder/go-i18n/i18n/language"
-)
-
-// Translation is the interface that represents a translated string.
-type Translation interface {
- // MarshalInterface returns the object that should be used
- // to serialize the translation.
- MarshalInterface() interface{}
- ID() string
- Template(language.Plural) *template
- UntranslatedCopy() Translation
- Normalize(language *language.Language) Translation
- Backfill(src Translation) Translation
- Merge(Translation) Translation
- Incomplete(l *language.Language) bool
-}
-
-// SortableByID implements sort.Interface for a slice of translations.
-type SortableByID []Translation
-
-func (a SortableByID) Len() int { return len(a) }
-func (a SortableByID) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a SortableByID) Less(i, j int) bool { return a[i].ID() < a[j].ID() }
-
-// NewTranslation reflects on data to create a new Translation.
-//
-// data["id"] must be a string and data["translation"] must be either a string
-// for a non-plural translation or a map[string]interface{} for a plural translation.
-func NewTranslation(data map[string]interface{}) (Translation, error) {
- id, ok := data["id"].(string)
- if !ok {
- return nil, fmt.Errorf(`missing "id" key`)
- }
- var pluralObject map[string]interface{}
- switch translation := data["translation"].(type) {
- case string:
- tmpl, err := newTemplate(translation)
- if err != nil {
- return nil, err
- }
- return &singleTranslation{id, tmpl}, nil
- case map[interface{}]interface{}:
- // The YAML parser uses interface{} keys so we first convert them to string keys.
- pluralObject = make(map[string]interface{})
- for k, v := range translation {
- kStr, ok := k.(string)
- if !ok {
- return nil, fmt.Errorf(`invalid plural category type %T; expected string`, k)
- }
- pluralObject[kStr] = v
- }
- case map[string]interface{}:
- pluralObject = translation
- case nil:
- return nil, fmt.Errorf(`missing "translation" key`)
- default:
- return nil, fmt.Errorf(`unsupported type for "translation" key %T`, translation)
- }
-
- templates := make(map[language.Plural]*template, len(pluralObject))
- for k, v := range pluralObject {
- pc, err := language.NewPlural(k)
- if err != nil {
- return nil, err
- }
- str, ok := v.(string)
- if !ok {
- return nil, fmt.Errorf(`plural category "%s" has value of type %T; expected string`, pc, v)
- }
- tmpl, err := newTemplate(str)
- if err != nil {
- return nil, err
- }
- templates[pc] = tmpl
- }
- return &pluralTranslation{id, templates}, nil
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS b/Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS
deleted file mode 100644
index b382a04ed..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS
+++ /dev/null
@@ -1 +0,0 @@
-Paul Borman <borman@google.com>
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/LICENSE b/Godeps/_workspace/src/github.com/pborman/uuid/LICENSE
deleted file mode 100644
index 5dc68268d..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009,2014 Google Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/dce.go b/Godeps/_workspace/src/github.com/pborman/uuid/dce.go
deleted file mode 100644
index 50a0f2d09..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/dce.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "encoding/binary"
- "fmt"
- "os"
-)
-
-// A Domain represents a Version 2 domain
-type Domain byte
-
-// Domain constants for DCE Security (Version 2) UUIDs.
-const (
- Person = Domain(0)
- Group = Domain(1)
- Org = Domain(2)
-)
-
-// NewDCESecurity returns a DCE Security (Version 2) UUID.
-//
-// The domain should be one of Person, Group or Org.
-// On a POSIX system the id should be the users UID for the Person
-// domain and the users GID for the Group. The meaning of id for
-// the domain Org or on non-POSIX systems is site defined.
-//
-// For a given domain/id pair the same token may be returned for up to
-// 7 minutes and 10 seconds.
-func NewDCESecurity(domain Domain, id uint32) UUID {
- uuid := NewUUID()
- if uuid != nil {
- uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
- uuid[9] = byte(domain)
- binary.BigEndian.PutUint32(uuid[0:], id)
- }
- return uuid
-}
-
-// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
-// domain with the id returned by os.Getuid.
-//
-// NewDCEPerson(Person, uint32(os.Getuid()))
-func NewDCEPerson() UUID {
- return NewDCESecurity(Person, uint32(os.Getuid()))
-}
-
-// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
-// domain with the id returned by os.Getgid.
-//
-// NewDCEGroup(Group, uint32(os.Getgid()))
-func NewDCEGroup() UUID {
- return NewDCESecurity(Group, uint32(os.Getgid()))
-}
-
-// Domain returns the domain for a Version 2 UUID or false.
-func (uuid UUID) Domain() (Domain, bool) {
- if v, _ := uuid.Version(); v != 2 {
- return 0, false
- }
- return Domain(uuid[9]), true
-}
-
-// Id returns the id for a Version 2 UUID or false.
-func (uuid UUID) Id() (uint32, bool) {
- if v, _ := uuid.Version(); v != 2 {
- return 0, false
- }
- return binary.BigEndian.Uint32(uuid[0:4]), true
-}
-
-func (d Domain) String() string {
- switch d {
- case Person:
- return "Person"
- case Group:
- return "Group"
- case Org:
- return "Org"
- }
- return fmt.Sprintf("Domain%d", int(d))
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/doc.go b/Godeps/_workspace/src/github.com/pborman/uuid/doc.go
deleted file mode 100644
index d8bd013e6..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The uuid package generates and inspects UUIDs.
-//
-// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
-package uuid
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/hash.go b/Godeps/_workspace/src/github.com/pborman/uuid/hash.go
deleted file mode 100644
index cdd4192fd..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/hash.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "crypto/md5"
- "crypto/sha1"
- "hash"
-)
-
-// Well known Name Space IDs and UUIDs
-var (
- NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
- NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
- NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
- NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
- NIL = Parse("00000000-0000-0000-0000-000000000000")
-)
-
-// NewHash returns a new UUID dervied from the hash of space concatenated with
-// data generated by h. The hash should be at least 16 byte in length. The
-// first 16 bytes of the hash are used to form the UUID. The version of the
-// UUID will be the lower 4 bits of version. NewHash is used to implement
-// NewMD5 and NewSHA1.
-func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
- h.Reset()
- h.Write(space)
- h.Write([]byte(data))
- s := h.Sum(nil)
- uuid := make([]byte, 16)
- copy(uuid, s)
- uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
- uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
- return uuid
-}
-
-// NewMD5 returns a new MD5 (Version 3) UUID based on the
-// supplied name space and data.
-//
-// NewHash(md5.New(), space, data, 3)
-func NewMD5(space UUID, data []byte) UUID {
- return NewHash(md5.New(), space, data, 3)
-}
-
-// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
-// supplied name space and data.
-//
-// NewHash(sha1.New(), space, data, 5)
-func NewSHA1(space UUID, data []byte) UUID {
- return NewHash(sha1.New(), space, data, 5)
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/json.go b/Godeps/_workspace/src/github.com/pborman/uuid/json.go
deleted file mode 100644
index 760580a50..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/json.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import "errors"
-
-func (u UUID) MarshalJSON() ([]byte, error) {
- if len(u) == 0 {
- return []byte(`""`), nil
- }
- return []byte(`"` + u.String() + `"`), nil
-}
-
-func (u *UUID) UnmarshalJSON(data []byte) error {
- if len(data) == 0 || string(data) == `""` {
- return nil
- }
- if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
- return errors.New("invalid UUID format")
- }
- data = data[1 : len(data)-1]
- uu := Parse(string(data))
- if uu == nil {
- return errors.New("invalid UUID format")
- }
- *u = uu
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/node.go b/Godeps/_workspace/src/github.com/pborman/uuid/node.go
deleted file mode 100644
index dd0a8ac18..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/node.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import "net"
-
-var (
- interfaces []net.Interface // cached list of interfaces
- ifname string // name of interface being used
- nodeID []byte // hardware for version 1 UUIDs
-)
-
-// NodeInterface returns the name of the interface from which the NodeID was
-// derived. The interface "user" is returned if the NodeID was set by
-// SetNodeID.
-func NodeInterface() string {
- return ifname
-}
-
-// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
-// If name is "" then the first usable interface found will be used or a random
-// Node ID will be generated. If a named interface cannot be found then false
-// is returned.
-//
-// SetNodeInterface never fails when name is "".
-func SetNodeInterface(name string) bool {
- if interfaces == nil {
- var err error
- interfaces, err = net.Interfaces()
- if err != nil && name != "" {
- return false
- }
- }
-
- for _, ifs := range interfaces {
- if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
- if setNodeID(ifs.HardwareAddr) {
- ifname = ifs.Name
- return true
- }
- }
- }
-
- // We found no interfaces with a valid hardware address. If name
- // does not specify a specific interface generate a random Node ID
- // (section 4.1.6)
- if name == "" {
- if nodeID == nil {
- nodeID = make([]byte, 6)
- }
- randomBits(nodeID)
- return true
- }
- return false
-}
-
-// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
-// if not already set.
-func NodeID() []byte {
- if nodeID == nil {
- SetNodeInterface("")
- }
- nid := make([]byte, 6)
- copy(nid, nodeID)
- return nid
-}
-
-// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
-// of id are used. If id is less than 6 bytes then false is returned and the
-// Node ID is not set.
-func SetNodeID(id []byte) bool {
- if setNodeID(id) {
- ifname = "user"
- return true
- }
- return false
-}
-
-func setNodeID(id []byte) bool {
- if len(id) < 6 {
- return false
- }
- if nodeID == nil {
- nodeID = make([]byte, 6)
- }
- copy(nodeID, id)
- return true
-}
-
-// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
-// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
-func (uuid UUID) NodeID() []byte {
- if len(uuid) != 16 {
- return nil
- }
- node := make([]byte, 6)
- copy(node, uuid[10:])
- return node
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/sql.go b/Godeps/_workspace/src/github.com/pborman/uuid/sql.go
deleted file mode 100644
index 98b23aa15..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/sql.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "errors"
- "fmt"
-)
-
-// Scan implements sql.Scanner so UUIDs can be read from databases transparently
-// Currently, database types that map to string and []byte are supported. Please
-// consult database-specific driver documentation for matching types.
-func (uuid *UUID) Scan(src interface{}) error {
- switch src.(type) {
- case string:
- // see uuid.Parse for required string format
- parsed := Parse(src.(string))
-
- if parsed == nil {
- return errors.New("Scan: invalid UUID format")
- }
-
- *uuid = parsed
- case []byte:
- b := src.([]byte)
-
- // assumes a simple slice of bytes if 16 bytes
- // otherwise attempts to parse
- if len(b) == 16 {
- *uuid = UUID(b)
- } else {
- u := Parse(string(b))
-
- if u == nil {
- return errors.New("Scan: invalid UUID format")
- }
-
- *uuid = u
- }
-
- default:
- return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
- }
-
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/time.go b/Godeps/_workspace/src/github.com/pborman/uuid/time.go
deleted file mode 100644
index 7ebc9bef1..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/time.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2014 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "encoding/binary"
- "sync"
- "time"
-)
-
-// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
-// 1582.
-type Time int64
-
-const (
- lillian = 2299160 // Julian day of 15 Oct 1582
- unix = 2440587 // Julian day of 1 Jan 1970
- epoch = unix - lillian // Days between epochs
- g1582 = epoch * 86400 // seconds between epochs
- g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
-)
-
-var (
- mu sync.Mutex
- lasttime uint64 // last time we returned
- clock_seq uint16 // clock sequence for this run
-
- timeNow = time.Now // for testing
-)
-
-// UnixTime converts t the number of seconds and nanoseconds using the Unix
-// epoch of 1 Jan 1970.
-func (t Time) UnixTime() (sec, nsec int64) {
- sec = int64(t - g1582ns100)
- nsec = (sec % 10000000) * 100
- sec /= 10000000
- return sec, nsec
-}
-
-// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
-// clock sequence as well as adjusting the clock sequence as needed. An error
-// is returned if the current time cannot be determined.
-func GetTime() (Time, uint16, error) {
- defer mu.Unlock()
- mu.Lock()
- return getTime()
-}
-
-func getTime() (Time, uint16, error) {
- t := timeNow()
-
- // If we don't have a clock sequence already, set one.
- if clock_seq == 0 {
- setClockSequence(-1)
- }
- now := uint64(t.UnixNano()/100) + g1582ns100
-
- // If time has gone backwards with this clock sequence then we
- // increment the clock sequence
- if now <= lasttime {
- clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
- }
- lasttime = now
- return Time(now), clock_seq, nil
-}
-
-// ClockSequence returns the current clock sequence, generating one if not
-// already set. The clock sequence is only used for Version 1 UUIDs.
-//
-// The uuid package does not use global static storage for the clock sequence or
-// the last time a UUID was generated. Unless SetClockSequence a new random
-// clock sequence is generated the first time a clock sequence is requested by
-// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
-// for
-func ClockSequence() int {
- defer mu.Unlock()
- mu.Lock()
- return clockSequence()
-}
-
-func clockSequence() int {
- if clock_seq == 0 {
- setClockSequence(-1)
- }
- return int(clock_seq & 0x3fff)
-}
-
-// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
-// -1 causes a new sequence to be generated.
-func SetClockSequence(seq int) {
- defer mu.Unlock()
- mu.Lock()
- setClockSequence(seq)
-}
-
-func setClockSequence(seq int) {
- if seq == -1 {
- var b [2]byte
- randomBits(b[:]) // clock sequence
- seq = int(b[0])<<8 | int(b[1])
- }
- old_seq := clock_seq
- clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
- if old_seq != clock_seq {
- lasttime = 0
- }
-}
-
-// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
-// uuid. It returns false if uuid is not valid. The time is only well defined
-// for version 1 and 2 UUIDs.
-func (uuid UUID) Time() (Time, bool) {
- if len(uuid) != 16 {
- return 0, false
- }
- time := int64(binary.BigEndian.Uint32(uuid[0:4]))
- time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
- time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
- return Time(time), true
-}
-
-// ClockSequence returns the clock sequence encoded in uuid. It returns false
-// if uuid is not valid. The clock sequence is only well defined for version 1
-// and 2 UUIDs.
-func (uuid UUID) ClockSequence() (int, bool) {
- if len(uuid) != 16 {
- return 0, false
- }
- return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/util.go b/Godeps/_workspace/src/github.com/pborman/uuid/util.go
deleted file mode 100644
index de40b102c..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/util.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "io"
-)
-
-// randomBits completely fills slice b with random data.
-func randomBits(b []byte) {
- if _, err := io.ReadFull(rander, b); err != nil {
- panic(err.Error()) // rand should never fail
- }
-}
-
-// xvalues returns the value of a byte as a hexadecimal digit or 255.
-var xvalues = []byte{
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
- 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-}
-
-// xtob converts the the first two hex bytes of x into a byte.
-func xtob(x string) (byte, bool) {
- b1 := xvalues[x[0]]
- b2 := xvalues[x[1]]
- return (b1 << 4) | b2, b1 != 255 && b2 != 255
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/uuid.go b/Godeps/_workspace/src/github.com/pborman/uuid/uuid.go
deleted file mode 100644
index 2920fae63..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/uuid.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "bytes"
- "crypto/rand"
- "fmt"
- "io"
- "strings"
-)
-
-// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
-// 4122.
-type UUID []byte
-
-// A Version represents a UUIDs version.
-type Version byte
-
-// A Variant represents a UUIDs variant.
-type Variant byte
-
-// Constants returned by Variant.
-const (
- Invalid = Variant(iota) // Invalid UUID
- RFC4122 // The variant specified in RFC4122
- Reserved // Reserved, NCS backward compatibility.
- Microsoft // Reserved, Microsoft Corporation backward compatibility.
- Future // Reserved for future definition.
-)
-
-var rander = rand.Reader // random function
-
-// New returns a new random (version 4) UUID as a string. It is a convenience
-// function for NewRandom().String().
-func New() string {
- return NewRandom().String()
-}
-
-// Parse decodes s into a UUID or returns nil. Both the UUID form of
-// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
-// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
-func Parse(s string) UUID {
- if len(s) == 36+9 {
- if strings.ToLower(s[:9]) != "urn:uuid:" {
- return nil
- }
- s = s[9:]
- } else if len(s) != 36 {
- return nil
- }
- if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
- return nil
- }
- uuid := make([]byte, 16)
- for i, x := range []int{
- 0, 2, 4, 6,
- 9, 11,
- 14, 16,
- 19, 21,
- 24, 26, 28, 30, 32, 34} {
- if v, ok := xtob(s[x:]); !ok {
- return nil
- } else {
- uuid[i] = v
- }
- }
- return uuid
-}
-
-// Equal returns true if uuid1 and uuid2 are equal.
-func Equal(uuid1, uuid2 UUID) bool {
- return bytes.Equal(uuid1, uuid2)
-}
-
-// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-// , or "" if uuid is invalid.
-func (uuid UUID) String() string {
- if uuid == nil || len(uuid) != 16 {
- return ""
- }
- b := []byte(uuid)
- return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x",
- b[:4], b[4:6], b[6:8], b[8:10], b[10:])
-}
-
-// URN returns the RFC 2141 URN form of uuid,
-// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
-func (uuid UUID) URN() string {
- if uuid == nil || len(uuid) != 16 {
- return ""
- }
- b := []byte(uuid)
- return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x",
- b[:4], b[4:6], b[6:8], b[8:10], b[10:])
-}
-
-// Variant returns the variant encoded in uuid. It returns Invalid if
-// uuid is invalid.
-func (uuid UUID) Variant() Variant {
- if len(uuid) != 16 {
- return Invalid
- }
- switch {
- case (uuid[8] & 0xc0) == 0x80:
- return RFC4122
- case (uuid[8] & 0xe0) == 0xc0:
- return Microsoft
- case (uuid[8] & 0xe0) == 0xe0:
- return Future
- default:
- return Reserved
- }
- panic("unreachable")
-}
-
-// Version returns the verison of uuid. It returns false if uuid is not
-// valid.
-func (uuid UUID) Version() (Version, bool) {
- if len(uuid) != 16 {
- return 0, false
- }
- return Version(uuid[6] >> 4), true
-}
-
-func (v Version) String() string {
- if v > 15 {
- return fmt.Sprintf("BAD_VERSION_%d", v)
- }
- return fmt.Sprintf("VERSION_%d", v)
-}
-
-func (v Variant) String() string {
- switch v {
- case RFC4122:
- return "RFC4122"
- case Reserved:
- return "Reserved"
- case Microsoft:
- return "Microsoft"
- case Future:
- return "Future"
- case Invalid:
- return "Invalid"
- }
- return fmt.Sprintf("BadVariant%d", int(v))
-}
-
-// SetRand sets the random number generator to r, which implents io.Reader.
-// If r.Read returns an error when the package requests random data then
-// a panic will be issued.
-//
-// Calling SetRand with nil sets the random number generator to the default
-// generator.
-func SetRand(r io.Reader) {
- if r == nil {
- rander = rand.Reader
- return
- }
- rander = r
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/version1.go b/Godeps/_workspace/src/github.com/pborman/uuid/version1.go
deleted file mode 100644
index 0127eacfa..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/version1.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-import (
- "encoding/binary"
-)
-
-// NewUUID returns a Version 1 UUID based on the current NodeID and clock
-// sequence, and the current time. If the NodeID has not been set by SetNodeID
-// or SetNodeInterface then it will be set automatically. If the NodeID cannot
-// be set NewUUID returns nil. If clock sequence has not been set by
-// SetClockSequence then it will be set automatically. If GetTime fails to
-// return the current NewUUID returns nil.
-func NewUUID() UUID {
- if nodeID == nil {
- SetNodeInterface("")
- }
-
- now, seq, err := GetTime()
- if err != nil {
- return nil
- }
-
- uuid := make([]byte, 16)
-
- time_low := uint32(now & 0xffffffff)
- time_mid := uint16((now >> 32) & 0xffff)
- time_hi := uint16((now >> 48) & 0x0fff)
- time_hi |= 0x1000 // Version 1
-
- binary.BigEndian.PutUint32(uuid[0:], time_low)
- binary.BigEndian.PutUint16(uuid[4:], time_mid)
- binary.BigEndian.PutUint16(uuid[6:], time_hi)
- binary.BigEndian.PutUint16(uuid[8:], seq)
- copy(uuid[10:], nodeID)
-
- return uuid
-}
diff --git a/Godeps/_workspace/src/github.com/pborman/uuid/version4.go b/Godeps/_workspace/src/github.com/pborman/uuid/version4.go
deleted file mode 100644
index b3d4a368d..000000000
--- a/Godeps/_workspace/src/github.com/pborman/uuid/version4.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package uuid
-
-// Random returns a Random (Version 4) UUID or panics.
-//
-// The strength of the UUIDs is based on the strength of the crypto/rand
-// package.
-//
-// A note about uniqueness derived from from the UUID Wikipedia entry:
-//
-// Randomly generated UUIDs have 122 random bits. One's annual risk of being
-// hit by a meteorite is estimated to be one chance in 17 billion, that
-// means the probability is about 0.00000000006 (6 × 10−11),
-// equivalent to the odds of creating a few tens of trillions of UUIDs in a
-// year and having one duplicate.
-func NewRandom() UUID {
- uuid := make([]byte, 16)
- randomBits([]byte(uuid))
- uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
- uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
- return uuid
-}
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/LICENSE b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/LICENSE
deleted file mode 100644
index aa6250465..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-
-Copyright (c) 2012, Robert Carlsen & Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/README.md b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/README.md
deleted file mode 100644
index b3bf5fa0e..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-To regenerate the regression test data, run `go generate` inside the exif
-package directory and commit the changes to *regress_expected_test.go*.
-
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/huge_tag_exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/huge_tag_exif.jpg
deleted file mode 100644
index ffb31743d..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/huge_tag_exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/infinite_loop_exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/infinite_loop_exif.jpg
deleted file mode 100644
index 6b0994713..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/infinite_loop_exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/max_uint32_exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/max_uint32_exif.jpg
deleted file mode 100644
index 2a51b0ba0..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/corrupt/max_uint32_exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/exif.go b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/exif.go
deleted file mode 100644
index b420729da..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/exif.go
+++ /dev/null
@@ -1,619 +0,0 @@
-// Package exif implements decoding of EXIF data as defined in the EXIF 2.2
-// specification (http://www.exif.org/Exif2-2.PDF).
-package exif
-
-import (
- "bufio"
- "bytes"
- "encoding/binary"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "math"
- "strconv"
- "strings"
- "time"
-
- "github.com/rwcarlsen/goexif/tiff"
-)
-
-const (
- jpeg_APP1 = 0xE1
-
- exifPointer = 0x8769
- gpsPointer = 0x8825
- interopPointer = 0xA005
-)
-
-// A decodeError is returned when the image cannot be decoded as a tiff image.
-type decodeError struct {
- cause error
-}
-
-func (de decodeError) Error() string {
- return fmt.Sprintf("exif: decode failed (%v) ", de.cause.Error())
-}
-
-// IsShortReadTagValueError identifies a ErrShortReadTagValue error.
-func IsShortReadTagValueError(err error) bool {
- de, ok := err.(decodeError)
- if ok {
- return de.cause == tiff.ErrShortReadTagValue
- }
- return false
-}
-
-// A TagNotPresentError is returned when the requested field is not
-// present in the EXIF.
-type TagNotPresentError FieldName
-
-func (tag TagNotPresentError) Error() string {
- return fmt.Sprintf("exif: tag %q is not present", string(tag))
-}
-
-func IsTagNotPresentError(err error) bool {
- _, ok := err.(TagNotPresentError)
- return ok
-}
-
-// Parser allows the registration of custom parsing and field loading
-// in the Decode function.
-type Parser interface {
- // Parse should read data from x and insert parsed fields into x via
- // LoadTags.
- Parse(x *Exif) error
-}
-
-var parsers []Parser
-
-func init() {
- RegisterParsers(&parser{})
-}
-
-// RegisterParsers registers one or more parsers to be automatically called
-// when decoding EXIF data via the Decode function.
-func RegisterParsers(ps ...Parser) {
- parsers = append(parsers, ps...)
-}
-
-type parser struct{}
-
-type tiffErrors map[tiffError]string
-
-func (te tiffErrors) Error() string {
- var allErrors []string
- for k, v := range te {
- allErrors = append(allErrors, fmt.Sprintf("%s: %v\n", stagePrefix[k], v))
- }
- return strings.Join(allErrors, "\n")
-}
-
-// IsCriticalError, given the error returned by Decode, reports whether the
-// returned *Exif may contain usable information.
-func IsCriticalError(err error) bool {
- _, ok := err.(tiffErrors)
- return !ok
-}
-
-// IsExifError reports whether the error happened while decoding the EXIF
-// sub-IFD.
-func IsExifError(err error) bool {
- if te, ok := err.(tiffErrors); ok {
- _, isExif := te[loadExif]
- return isExif
- }
- return false
-}
-
-// IsGPSError reports whether the error happened while decoding the GPS sub-IFD.
-func IsGPSError(err error) bool {
- if te, ok := err.(tiffErrors); ok {
- _, isGPS := te[loadExif]
- return isGPS
- }
- return false
-}
-
-// IsInteroperabilityError reports whether the error happened while decoding the
-// Interoperability sub-IFD.
-func IsInteroperabilityError(err error) bool {
- if te, ok := err.(tiffErrors); ok {
- _, isInterop := te[loadInteroperability]
- return isInterop
- }
- return false
-}
-
-type tiffError int
-
-const (
- loadExif tiffError = iota
- loadGPS
- loadInteroperability
-)
-
-var stagePrefix = map[tiffError]string{
- loadExif: "loading EXIF sub-IFD",
- loadGPS: "loading GPS sub-IFD",
- loadInteroperability: "loading Interoperability sub-IFD",
-}
-
-// Parse reads data from the tiff data in x and populates the tags
-// in x. If parsing a sub-IFD fails, the error is recorded and
-// parsing continues with the remaining sub-IFDs.
-func (p *parser) Parse(x *Exif) error {
- x.LoadTags(x.Tiff.Dirs[0], exifFields, false)
-
- // thumbnails
- if len(x.Tiff.Dirs) >= 2 {
- x.LoadTags(x.Tiff.Dirs[1], thumbnailFields, false)
- }
-
- te := make(tiffErrors)
-
- // recurse into exif, gps, and interop sub-IFDs
- if err := loadSubDir(x, ExifIFDPointer, exifFields); err != nil {
- te[loadExif] = err.Error()
- }
- if err := loadSubDir(x, GPSInfoIFDPointer, gpsFields); err != nil {
- te[loadGPS] = err.Error()
- }
-
- if err := loadSubDir(x, InteroperabilityIFDPointer, interopFields); err != nil {
- te[loadInteroperability] = err.Error()
- }
- if len(te) > 0 {
- return te
- }
- return nil
-}
-
-func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error {
- r := bytes.NewReader(x.Raw)
-
- tag, err := x.Get(ptr)
- if err != nil {
- return nil
- }
- offset, err := tag.Int64(0)
- if err != nil {
- return nil
- }
-
- _, err = r.Seek(offset, 0)
- if err != nil {
- return fmt.Errorf("exif: seek to sub-IFD %s failed: %v", ptr, err)
- }
- subDir, _, err := tiff.DecodeDir(r, x.Tiff.Order)
- if err != nil {
- return fmt.Errorf("exif: sub-IFD %s decode failed: %v", ptr, err)
- }
- x.LoadTags(subDir, fieldMap, false)
- return nil
-}
-
-// Exif provides access to decoded EXIF metadata fields and values.
-type Exif struct {
- Tiff *tiff.Tiff
- main map[FieldName]*tiff.Tag
- Raw []byte
-}
-
-// Decode parses EXIF-encoded data from r and returns a queryable Exif
-// object. After the exif data section is called and the tiff structure
-// decoded, each registered parser is called (in order of registration). If
-// one parser returns an error, decoding terminates and the remaining
-// parsers are not called.
-// The error can be inspected with functions such as IsCriticalError to
-// determine whether the returned object might still be usable.
-func Decode(r io.Reader) (*Exif, error) {
- // EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF
- // format to store data.
- // If we're parsing a TIFF image, we don't need to strip away any data.
- // If we're parsing a JPEG image, we need to strip away the JPEG APP1
- // marker and also the EXIF header.
-
- header := make([]byte, 4)
- n, err := r.Read(header)
- if err != nil {
- return nil, err
- }
- if n < len(header) {
- return nil, errors.New("exif: short read on header")
- }
-
- var isTiff bool
- switch string(header) {
- case "II*\x00":
- // TIFF - Little endian (Intel)
- isTiff = true
- case "MM\x00*":
- // TIFF - Big endian (Motorola)
- isTiff = true
- default:
- // Not TIFF, assume JPEG
- }
-
- // Put the header bytes back into the reader.
- r = io.MultiReader(bytes.NewReader(header), r)
- var (
- er *bytes.Reader
- tif *tiff.Tiff
- )
-
- if isTiff {
- // Functions below need the IFDs from the TIFF data to be stored in a
- // *bytes.Reader. We use TeeReader to get a copy of the bytes as a
- // side-effect of tiff.Decode() doing its work.
- b := &bytes.Buffer{}
- tr := io.TeeReader(r, b)
- tif, err = tiff.Decode(tr)
- er = bytes.NewReader(b.Bytes())
- } else {
- // Locate the JPEG APP1 header.
- var sec *appSec
- sec, err = newAppSec(jpeg_APP1, r)
- if err != nil {
- return nil, err
- }
- // Strip away EXIF header.
- er, err = sec.exifReader()
- if err != nil {
- return nil, err
- }
- tif, err = tiff.Decode(er)
- }
-
- if err != nil {
- return nil, decodeError{cause: err}
- }
-
- er.Seek(0, 0)
- raw, err := ioutil.ReadAll(er)
- if err != nil {
- return nil, decodeError{cause: err}
- }
-
- // build an exif structure from the tiff
- x := &Exif{
- main: map[FieldName]*tiff.Tag{},
- Tiff: tif,
- Raw: raw,
- }
-
- for i, p := range parsers {
- if err := p.Parse(x); err != nil {
- if _, ok := err.(tiffErrors); ok {
- return x, err
- }
- // This should never happen, as Parse always returns a tiffError
- // for now, but that could change.
- return x, fmt.Errorf("exif: parser %v failed (%v)", i, err)
- }
- }
-
- return x, nil
-}
-
-// LoadTags loads tags into the available fields from the tiff Directory
-// using the given tagid-fieldname mapping. Used to load makernote and
-// other meta-data. If showMissing is true, tags in d that are not in the
-// fieldMap will be loaded with the FieldName UnknownPrefix followed by the
-// tag ID (in hex format).
-func (x *Exif) LoadTags(d *tiff.Dir, fieldMap map[uint16]FieldName, showMissing bool) {
- for _, tag := range d.Tags {
- name := fieldMap[tag.Id]
- if name == "" {
- if !showMissing {
- continue
- }
- name = FieldName(fmt.Sprintf("%v%x", UnknownPrefix, tag.Id))
- }
- x.main[name] = tag
- }
-}
-
-// Get retrieves the EXIF tag for the given field name.
-//
-// If the tag is not known or not present, an error is returned. If the
-// tag name is known, the error will be a TagNotPresentError.
-func (x *Exif) Get(name FieldName) (*tiff.Tag, error) {
- if tg, ok := x.main[name]; ok {
- return tg, nil
- }
- return nil, TagNotPresentError(name)
-}
-
-// Walker is the interface used to traverse all fields of an Exif object.
-type Walker interface {
- // Walk is called for each non-nil EXIF field. Returning a non-nil
- // error aborts the walk/traversal.
- Walk(name FieldName, tag *tiff.Tag) error
-}
-
-// Walk calls the Walk method of w with the name and tag for every non-nil
-// EXIF field. If w aborts the walk with an error, that error is returned.
-func (x *Exif) Walk(w Walker) error {
- for name, tag := range x.main {
- if err := w.Walk(name, tag); err != nil {
- return err
- }
- }
- return nil
-}
-
-// DateTime returns the EXIF's "DateTimeOriginal" field, which
-// is the creation time of the photo. If not found, it tries
-// the "DateTime" (which is meant as the modtime) instead.
-// The error will be TagNotPresentErr if none of those tags
-// were found, or a generic error if the tag value was
-// not a string, or the error returned by time.Parse.
-//
-// If the EXIF lacks timezone information or GPS time, the returned
-// time's Location will be time.Local.
-func (x *Exif) DateTime() (time.Time, error) {
- var dt time.Time
- tag, err := x.Get(DateTimeOriginal)
- if err != nil {
- tag, err = x.Get(DateTime)
- if err != nil {
- return dt, err
- }
- }
- if tag.Format() != tiff.StringVal {
- return dt, errors.New("DateTime[Original] not in string format")
- }
- exifTimeLayout := "2006:01:02 15:04:05"
- dateStr := strings.TrimRight(string(tag.Val), "\x00")
- // TODO(bradfitz,mpl): look for timezone offset, GPS time, etc.
- // For now, just always return the time.Local timezone.
- return time.ParseInLocation(exifTimeLayout, dateStr, time.Local)
-}
-
-func ratFloat(num, dem int64) float64 {
- return float64(num) / float64(dem)
-}
-
-// Tries to parse a Geo degrees value from a string as it was found in some
-// EXIF data.
-// Supported formats so far:
-// - "52,00000,50,00000,34,01180" ==> 52 deg 50'34.0118"
-// Probably due to locale the comma is used as decimal mark as well as the
-// separator of three floats (degrees, minutes, seconds)
-// http://en.wikipedia.org/wiki/Decimal_mark#Hindu.E2.80.93Arabic_numeral_system
-// - "52.0,50.0,34.01180" ==> 52deg50'34.0118"
-// - "52,50,34.01180" ==> 52deg50'34.0118"
-func parseTagDegreesString(s string) (float64, error) {
- const unparsableErrorFmt = "Unknown coordinate format: %s"
- isSplitRune := func(c rune) bool {
- return c == ',' || c == ';'
- }
- parts := strings.FieldsFunc(s, isSplitRune)
- var degrees, minutes, seconds float64
- var err error
- switch len(parts) {
- case 6:
- degrees, err = strconv.ParseFloat(parts[0]+"."+parts[1], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- minutes, err = strconv.ParseFloat(parts[2]+"."+parts[3], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- minutes = math.Copysign(minutes, degrees)
- seconds, err = strconv.ParseFloat(parts[4]+"."+parts[5], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- seconds = math.Copysign(seconds, degrees)
- case 3:
- degrees, err = strconv.ParseFloat(parts[0], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- minutes, err = strconv.ParseFloat(parts[1], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- minutes = math.Copysign(minutes, degrees)
- seconds, err = strconv.ParseFloat(parts[2], 64)
- if err != nil {
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- seconds = math.Copysign(seconds, degrees)
- default:
- return 0.0, fmt.Errorf(unparsableErrorFmt, s)
- }
- return degrees + minutes/60.0 + seconds/3600.0, nil
-}
-
-func parse3Rat2(tag *tiff.Tag) ([3]float64, error) {
- v := [3]float64{}
- for i := range v {
- num, den, err := tag.Rat2(i)
- if err != nil {
- return v, err
- }
- v[i] = ratFloat(num, den)
- if tag.Count < uint32(i+2) {
- break
- }
- }
- return v, nil
-}
-
-func tagDegrees(tag *tiff.Tag) (float64, error) {
- switch tag.Format() {
- case tiff.RatVal:
- // The usual case, according to the Exif spec
- // (http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf,
- // sec 4.6.6, p. 52 et seq.)
- v, err := parse3Rat2(tag)
- if err != nil {
- return 0.0, err
- }
- return v[0] + v[1]/60 + v[2]/3600.0, nil
- case tiff.StringVal:
- // Encountered this weird case with a panorama picture taken with a HTC phone
- s, err := tag.StringVal()
- if err != nil {
- return 0.0, err
- }
- return parseTagDegreesString(s)
- default:
- // don't know how to parse value, give up
- return 0.0, fmt.Errorf("Malformed EXIF Tag Degrees")
- }
-}
-
-// LatLong returns the latitude and longitude of the photo and
-// whether it was present.
-func (x *Exif) LatLong() (lat, long float64, err error) {
- // All calls of x.Get might return an TagNotPresentError
- longTag, err := x.Get(FieldName("GPSLongitude"))
- if err != nil {
- return
- }
- ewTag, err := x.Get(FieldName("GPSLongitudeRef"))
- if err != nil {
- return
- }
- latTag, err := x.Get(FieldName("GPSLatitude"))
- if err != nil {
- return
- }
- nsTag, err := x.Get(FieldName("GPSLatitudeRef"))
- if err != nil {
- return
- }
- if long, err = tagDegrees(longTag); err != nil {
- return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
- }
- if lat, err = tagDegrees(latTag); err != nil {
- return 0, 0, fmt.Errorf("Cannot parse latitude: %v", err)
- }
- ew, err := ewTag.StringVal()
- if err == nil && ew == "W" {
- long *= -1.0
- } else if err != nil {
- return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
- }
- ns, err := nsTag.StringVal()
- if err == nil && ns == "S" {
- lat *= -1.0
- } else if err != nil {
- return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
- }
- return lat, long, nil
-}
-
-// String returns a pretty text representation of the decoded exif data.
-func (x *Exif) String() string {
- var buf bytes.Buffer
- for name, tag := range x.main {
- fmt.Fprintf(&buf, "%s: %s\n", name, tag)
- }
- return buf.String()
-}
-
-// JpegThumbnail returns the jpeg thumbnail if it exists. If it doesn't exist,
-// TagNotPresentError will be returned
-func (x *Exif) JpegThumbnail() ([]byte, error) {
- offset, err := x.Get(ThumbJPEGInterchangeFormat)
- if err != nil {
- return nil, err
- }
- start, err := offset.Int(0)
- if err != nil {
- return nil, err
- }
-
- length, err := x.Get(ThumbJPEGInterchangeFormatLength)
- if err != nil {
- return nil, err
- }
- l, err := length.Int(0)
- if err != nil {
- return nil, err
- }
-
- return x.Raw[start : start+l], nil
-}
-
-// MarshalJson implements the encoding/json.Marshaler interface providing output of
-// all EXIF fields present (names and values).
-func (x Exif) MarshalJSON() ([]byte, error) {
- return json.Marshal(x.main)
-}
-
-type appSec struct {
- marker byte
- data []byte
-}
-
-// newAppSec finds marker in r and returns the corresponding application data
-// section.
-func newAppSec(marker byte, r io.Reader) (*appSec, error) {
- br := bufio.NewReader(r)
- app := &appSec{marker: marker}
- var dataLen int
-
- // seek to marker
- for dataLen == 0 {
- if _, err := br.ReadBytes(0xFF); err != nil {
- return nil, err
- }
- c, err := br.ReadByte()
- if err != nil {
- return nil, err
- } else if c != marker {
- continue
- }
-
- dataLenBytes := make([]byte, 2)
- for k,_ := range dataLenBytes {
- c, err := br.ReadByte()
- if err != nil {
- return nil, err
- }
- dataLenBytes[k] = c
- }
- dataLen = int(binary.BigEndian.Uint16(dataLenBytes)) - 2
- }
-
- // read section data
- nread := 0
- for nread < dataLen {
- s := make([]byte, dataLen-nread)
- n, err := br.Read(s)
- nread += n
- if err != nil && nread < dataLen {
- return nil, err
- }
- app.data = append(app.data, s[:n]...)
- }
- return app, nil
-}
-
-// reader returns a reader on this appSec.
-func (app *appSec) reader() *bytes.Reader {
- return bytes.NewReader(app.data)
-}
-
-// exifReader returns a reader on this appSec with the read cursor advanced to
-// the start of the exif's tiff encoded portion.
-func (app *appSec) exifReader() (*bytes.Reader, error) {
- if len(app.data) < 6 {
- return nil, errors.New("exif: failed to find exif intro marker")
- }
-
- // read/check for exif special mark
- exif := app.data[:6]
- if !bytes.Equal(exif, append([]byte("Exif"), 0x00, 0x00)) {
- return nil, errors.New("exif: failed to find exif intro marker")
- }
- return bytes.NewReader(app.data[6:]), nil
-}
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/fields.go b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/fields.go
deleted file mode 100644
index 0388d2390..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/fields.go
+++ /dev/null
@@ -1,293 +0,0 @@
-package exif
-
-type FieldName string
-
-// UnknownPrefix is used as the first part of field names for decoded tags for
-// which there is no known/supported EXIF field.
-const UnknownPrefix = "UnknownTag_"
-
-// Primary EXIF fields
-const (
- ImageWidth FieldName = "ImageWidth"
- ImageLength = "ImageLength" // Image height called Length by EXIF spec
- BitsPerSample = "BitsPerSample"
- Compression = "Compression"
- PhotometricInterpretation = "PhotometricInterpretation"
- Orientation = "Orientation"
- SamplesPerPixel = "SamplesPerPixel"
- PlanarConfiguration = "PlanarConfiguration"
- YCbCrSubSampling = "YCbCrSubSampling"
- YCbCrPositioning = "YCbCrPositioning"
- XResolution = "XResolution"
- YResolution = "YResolution"
- ResolutionUnit = "ResolutionUnit"
- DateTime = "DateTime"
- ImageDescription = "ImageDescription"
- Make = "Make"
- Model = "Model"
- Software = "Software"
- Artist = "Artist"
- Copyright = "Copyright"
- ExifIFDPointer = "ExifIFDPointer"
- GPSInfoIFDPointer = "GPSInfoIFDPointer"
- InteroperabilityIFDPointer = "InteroperabilityIFDPointer"
- ExifVersion = "ExifVersion"
- FlashpixVersion = "FlashpixVersion"
- ColorSpace = "ColorSpace"
- ComponentsConfiguration = "ComponentsConfiguration"
- CompressedBitsPerPixel = "CompressedBitsPerPixel"
- PixelXDimension = "PixelXDimension"
- PixelYDimension = "PixelYDimension"
- MakerNote = "MakerNote"
- UserComment = "UserComment"
- RelatedSoundFile = "RelatedSoundFile"
- DateTimeOriginal = "DateTimeOriginal"
- DateTimeDigitized = "DateTimeDigitized"
- SubSecTime = "SubSecTime"
- SubSecTimeOriginal = "SubSecTimeOriginal"
- SubSecTimeDigitized = "SubSecTimeDigitized"
- ImageUniqueID = "ImageUniqueID"
- ExposureTime = "ExposureTime"
- FNumber = "FNumber"
- ExposureProgram = "ExposureProgram"
- SpectralSensitivity = "SpectralSensitivity"
- ISOSpeedRatings = "ISOSpeedRatings"
- OECF = "OECF"
- ShutterSpeedValue = "ShutterSpeedValue"
- ApertureValue = "ApertureValue"
- BrightnessValue = "BrightnessValue"
- ExposureBiasValue = "ExposureBiasValue"
- MaxApertureValue = "MaxApertureValue"
- SubjectDistance = "SubjectDistance"
- MeteringMode = "MeteringMode"
- LightSource = "LightSource"
- Flash = "Flash"
- FocalLength = "FocalLength"
- SubjectArea = "SubjectArea"
- FlashEnergy = "FlashEnergy"
- SpatialFrequencyResponse = "SpatialFrequencyResponse"
- FocalPlaneXResolution = "FocalPlaneXResolution"
- FocalPlaneYResolution = "FocalPlaneYResolution"
- FocalPlaneResolutionUnit = "FocalPlaneResolutionUnit"
- SubjectLocation = "SubjectLocation"
- ExposureIndex = "ExposureIndex"
- SensingMethod = "SensingMethod"
- FileSource = "FileSource"
- SceneType = "SceneType"
- CFAPattern = "CFAPattern"
- CustomRendered = "CustomRendered"
- ExposureMode = "ExposureMode"
- WhiteBalance = "WhiteBalance"
- DigitalZoomRatio = "DigitalZoomRatio"
- FocalLengthIn35mmFilm = "FocalLengthIn35mmFilm"
- SceneCaptureType = "SceneCaptureType"
- GainControl = "GainControl"
- Contrast = "Contrast"
- Saturation = "Saturation"
- Sharpness = "Sharpness"
- DeviceSettingDescription = "DeviceSettingDescription"
- SubjectDistanceRange = "SubjectDistanceRange"
- LensMake = "LensMake"
- LensModel = "LensModel"
-)
-
-// thumbnail fields
-const (
- ThumbJPEGInterchangeFormat = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI
- ThumbJPEGInterchangeFormatLength = "ThumbJPEGInterchangeFormatLength" // byte length of thumb
-)
-
-// GPS fields
-const (
- GPSVersionID FieldName = "GPSVersionID"
- GPSLatitudeRef = "GPSLatitudeRef"
- GPSLatitude = "GPSLatitude"
- GPSLongitudeRef = "GPSLongitudeRef"
- GPSLongitude = "GPSLongitude"
- GPSAltitudeRef = "GPSAltitudeRef"
- GPSAltitude = "GPSAltitude"
- GPSTimeStamp = "GPSTimeStamp"
- GPSSatelites = "GPSSatelites"
- GPSStatus = "GPSStatus"
- GPSMeasureMode = "GPSMeasureMode"
- GPSDOP = "GPSDOP"
- GPSSpeedRef = "GPSSpeedRef"
- GPSSpeed = "GPSSpeed"
- GPSTrackRef = "GPSTrackRef"
- GPSTrack = "GPSTrack"
- GPSImgDirectionRef = "GPSImgDirectionRef"
- GPSImgDirection = "GPSImgDirection"
- GPSMapDatum = "GPSMapDatum"
- GPSDestLatitudeRef = "GPSDestLatitudeRef"
- GPSDestLatitude = "GPSDestLatitude"
- GPSDestLongitudeRef = "GPSDestLongitudeRef"
- GPSDestLongitude = "GPSDestLongitude"
- GPSDestBearingRef = "GPSDestBearingRef"
- GPSDestBearing = "GPSDestBearing"
- GPSDestDistanceRef = "GPSDestDistanceRef"
- GPSDestDistance = "GPSDestDistance"
- GPSProcessingMethod = "GPSProcessingMethod"
- GPSAreaInformation = "GPSAreaInformation"
- GPSDateStamp = "GPSDateStamp"
- GPSDifferential = "GPSDifferential"
-)
-
-// interoperability fields
-const (
- InteroperabilityIndex FieldName = "InteroperabilityIndex"
-)
-
-var exifFields = map[uint16]FieldName{
- /////////////////////////////////////
- ////////// IFD 0 ////////////////////
- /////////////////////////////////////
-
- // image data structure for the thumbnail
- 0x0100: ImageWidth,
- 0x0101: ImageLength,
- 0x0102: BitsPerSample,
- 0x0103: Compression,
- 0x0106: PhotometricInterpretation,
- 0x0112: Orientation,
- 0x0115: SamplesPerPixel,
- 0x011C: PlanarConfiguration,
- 0x0212: YCbCrSubSampling,
- 0x0213: YCbCrPositioning,
- 0x011A: XResolution,
- 0x011B: YResolution,
- 0x0128: ResolutionUnit,
-
- // Other tags
- 0x0132: DateTime,
- 0x010E: ImageDescription,
- 0x010F: Make,
- 0x0110: Model,
- 0x0131: Software,
- 0x013B: Artist,
- 0x8298: Copyright,
-
- // private tags
- exifPointer: ExifIFDPointer,
-
- /////////////////////////////////////
- ////////// Exif sub IFD /////////////
- /////////////////////////////////////
-
- gpsPointer: GPSInfoIFDPointer,
- interopPointer: InteroperabilityIFDPointer,
-
- 0x9000: ExifVersion,
- 0xA000: FlashpixVersion,
-
- 0xA001: ColorSpace,
-
- 0x9101: ComponentsConfiguration,
- 0x9102: CompressedBitsPerPixel,
- 0xA002: PixelXDimension,
- 0xA003: PixelYDimension,
-
- 0x927C: MakerNote,
- 0x9286: UserComment,
-
- 0xA004: RelatedSoundFile,
- 0x9003: DateTimeOriginal,
- 0x9004: DateTimeDigitized,
- 0x9290: SubSecTime,
- 0x9291: SubSecTimeOriginal,
- 0x9292: SubSecTimeDigitized,
-
- 0xA420: ImageUniqueID,
-
- // picture conditions
- 0x829A: ExposureTime,
- 0x829D: FNumber,
- 0x8822: ExposureProgram,
- 0x8824: SpectralSensitivity,
- 0x8827: ISOSpeedRatings,
- 0x8828: OECF,
- 0x9201: ShutterSpeedValue,
- 0x9202: ApertureValue,
- 0x9203: BrightnessValue,
- 0x9204: ExposureBiasValue,
- 0x9205: MaxApertureValue,
- 0x9206: SubjectDistance,
- 0x9207: MeteringMode,
- 0x9208: LightSource,
- 0x9209: Flash,
- 0x920A: FocalLength,
- 0x9214: SubjectArea,
- 0xA20B: FlashEnergy,
- 0xA20C: SpatialFrequencyResponse,
- 0xA20E: FocalPlaneXResolution,
- 0xA20F: FocalPlaneYResolution,
- 0xA210: FocalPlaneResolutionUnit,
- 0xA214: SubjectLocation,
- 0xA215: ExposureIndex,
- 0xA217: SensingMethod,
- 0xA300: FileSource,
- 0xA301: SceneType,
- 0xA302: CFAPattern,
- 0xA401: CustomRendered,
- 0xA402: ExposureMode,
- 0xA403: WhiteBalance,
- 0xA404: DigitalZoomRatio,
- 0xA405: FocalLengthIn35mmFilm,
- 0xA406: SceneCaptureType,
- 0xA407: GainControl,
- 0xA408: Contrast,
- 0xA409: Saturation,
- 0xA40A: Sharpness,
- 0xA40B: DeviceSettingDescription,
- 0xA40C: SubjectDistanceRange,
- 0xA433: LensMake,
- 0xA434: LensModel,
-}
-
-var gpsFields = map[uint16]FieldName{
- /////////////////////////////////////
- //// GPS sub-IFD ////////////////////
- /////////////////////////////////////
- 0x0: GPSVersionID,
- 0x1: GPSLatitudeRef,
- 0x2: GPSLatitude,
- 0x3: GPSLongitudeRef,
- 0x4: GPSLongitude,
- 0x5: GPSAltitudeRef,
- 0x6: GPSAltitude,
- 0x7: GPSTimeStamp,
- 0x8: GPSSatelites,
- 0x9: GPSStatus,
- 0xA: GPSMeasureMode,
- 0xB: GPSDOP,
- 0xC: GPSSpeedRef,
- 0xD: GPSSpeed,
- 0xE: GPSTrackRef,
- 0xF: GPSTrack,
- 0x10: GPSImgDirectionRef,
- 0x11: GPSImgDirection,
- 0x12: GPSMapDatum,
- 0x13: GPSDestLatitudeRef,
- 0x14: GPSDestLatitude,
- 0x15: GPSDestLongitudeRef,
- 0x16: GPSDestLongitude,
- 0x17: GPSDestBearingRef,
- 0x18: GPSDestBearing,
- 0x19: GPSDestDistanceRef,
- 0x1A: GPSDestDistance,
- 0x1B: GPSProcessingMethod,
- 0x1C: GPSAreaInformation,
- 0x1D: GPSDateStamp,
- 0x1E: GPSDifferential,
-}
-
-var interopFields = map[uint16]FieldName{
- /////////////////////////////////////
- //// Interoperability sub-IFD ///////
- /////////////////////////////////////
- 0x1: InteroperabilityIndex,
-}
-
-var thumbnailFields = map[uint16]FieldName{
- 0x0201: ThumbJPEGInterchangeFormat,
- 0x0202: ThumbJPEGInterchangeFormatLength,
-}
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/regen_regress.go b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/regen_regress.go
deleted file mode 100644
index 17bac5287..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/regen_regress.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// +build ignore
-
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "log"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/rwcarlsen/goexif/exif"
- "github.com/rwcarlsen/goexif/tiff"
-)
-
-func main() {
- flag.Parse()
- fname := flag.Arg(0)
-
- dst, err := os.Create(fname)
- if err != nil {
- log.Fatal(err)
- }
- defer dst.Close()
-
- dir, err := os.Open("samples")
- if err != nil {
- log.Fatal(err)
- }
- defer dir.Close()
-
- names, err := dir.Readdirnames(0)
- if err != nil {
- log.Fatal(err)
- }
- for i, name := range names {
- names[i] = filepath.Join("samples", name)
- }
- makeExpected(names, dst)
-}
-
-func makeExpected(files []string, w io.Writer) {
- fmt.Fprintf(w, "package exif\n\n")
- fmt.Fprintf(w, "var regressExpected = map[string]map[FieldName]string{\n")
-
- for _, name := range files {
- f, err := os.Open(name)
- if err != nil {
- continue
- }
-
- x, err := exif.Decode(f)
- if err != nil {
- f.Close()
- continue
- }
-
- fmt.Fprintf(w, "\"%v\": map[FieldName]string{\n", filepath.Base(name))
- x.Walk(&regresswalk{w})
- fmt.Fprintf(w, "},\n")
- f.Close()
- }
- fmt.Fprintf(w, "}")
-}
-
-type regresswalk struct {
- wr io.Writer
-}
-
-func (w *regresswalk) Walk(name exif.FieldName, tag *tiff.Tag) error {
- if strings.HasPrefix(string(name), exif.UnknownPrefix) {
- fmt.Fprintf(w.wr, "\"%v\": `%v`,\n", name, tag.String())
- } else {
- fmt.Fprintf(w.wr, "%v: `%v`,\n", name, tag.String())
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/sample1.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/sample1.jpg
deleted file mode 100644
index 87bcf8e33..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/sample1.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2004-01-11-22-45-15-sep-2004-01-11-22-45-15a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2004-01-11-22-45-15-sep-2004-01-11-22-45-15a.jpg
deleted file mode 100644
index 6f3be2480..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2004-01-11-22-45-15-sep-2004-01-11-22-45-15a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-08-03-16-29-38-sep-2006-08-03-16-29-38a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-08-03-16-29-38-sep-2006-08-03-16-29-38a.jpg
deleted file mode 100644
index 39891df84..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-08-03-16-29-38-sep-2006-08-03-16-29-38a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-11-11-19-17-56-sep-2006-11-11-19-17-56a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-11-11-19-17-56-sep-2006-11-11-19-17-56a.jpg
deleted file mode 100644
index 4721e7542..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-11-11-19-17-56-sep-2006-11-11-19-17-56a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-10-23-58-20-sep-2006-12-10-23-58-20a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-10-23-58-20-sep-2006-12-10-23-58-20a.jpg
deleted file mode 100644
index 8c0997ea0..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-10-23-58-20-sep-2006-12-10-23-58-20a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-17-07-09-14-sep-2006-12-17-07-09-14a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-17-07-09-14-sep-2006-12-17-07-09-14a.jpg
deleted file mode 100644
index 1c6e7601d..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-17-07-09-14-sep-2006-12-17-07-09-14a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-21-15-55-26-sep-2006-12-21-15-55-26a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-21-15-55-26-sep-2006-12-21-15-55-26a.jpg
deleted file mode 100644
index 8aaf632be..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2006-12-21-15-55-26-sep-2006-12-21-15-55-26a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-01-12-00-00-sep-2007-01-01-12-00-00a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-01-12-00-00-sep-2007-01-01-12-00-00a.jpg
deleted file mode 100644
index c44db32c1..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-01-12-00-00-sep-2007-01-01-12-00-00a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-17-21-49-44-sep-2007-01-17-21-49-44a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-17-21-49-44-sep-2007-01-17-21-49-44a.jpg
deleted file mode 100644
index f025460d6..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-01-17-21-49-44-sep-2007-01-17-21-49-44a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-02-02-18-13-29-sep-2007-02-02-18-13-29a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-02-02-18-13-29-sep-2007-02-02-18-13-29a.jpg
deleted file mode 100644
index 3f1fbfbdf..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-02-02-18-13-29-sep-2007-02-02-18-13-29a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-02-17-02-21-sep-2007-05-02-17-02-21a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-02-17-02-21-sep-2007-05-02-17-02-21a.jpg
deleted file mode 100644
index 351935778..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-02-17-02-21-sep-2007-05-02-17-02-21a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-12-08-19-07-sep-2007-05-12-08-19-07a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-12-08-19-07-sep-2007-05-12-08-19-07a.jpg
deleted file mode 100644
index 175b60663..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-12-08-19-07-sep-2007-05-12-08-19-07a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-26-04-49-45-sep-2007-05-26-04-49-45a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-26-04-49-45-sep-2007-05-26-04-49-45a.jpg
deleted file mode 100644
index 90a6c92b0..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-26-04-49-45-sep-2007-05-26-04-49-45a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-30-14-28-01-sep-2007-05-30-14-28-01a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-30-14-28-01-sep-2007-05-30-14-28-01a.jpg
deleted file mode 100644
index 74f30c351..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-05-30-14-28-01-sep-2007-05-30-14-28-01a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-06-16-15-25-sep-2007-06-06-16-15-25a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-06-16-15-25-sep-2007-06-06-16-15-25a.jpg
deleted file mode 100644
index 0a025a0b8..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-06-16-15-25-sep-2007-06-06-16-15-25a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-26-10-13-04-sep-2007-06-26-10-13-04a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-26-10-13-04-sep-2007-06-26-10-13-04a.jpg
deleted file mode 100644
index 526cefafd..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-06-26-10-13-04-sep-2007-06-26-10-13-04a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-07-13-17-02-30-sep-2007-07-13-17-02-30a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-07-13-17-02-30-sep-2007-07-13-17-02-30a.jpg
deleted file mode 100644
index c39e90fca..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-07-13-17-02-30-sep-2007-07-13-17-02-30a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-15-14-42-46-sep-2007-08-15-14-42-46a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-15-14-42-46-sep-2007-08-15-14-42-46a.jpg
deleted file mode 100644
index 81be2a200..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-15-14-42-46-sep-2007-08-15-14-42-46a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-24-02-40-42-sep-2007-08-24-02-40-42a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-24-02-40-42-sep-2007-08-24-02-40-42a.jpg
deleted file mode 100644
index aa457643d..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-08-24-02-40-42-sep-2007-08-24-02-40-42a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-11-07-11-40-44-sep-2007-11-07-11-40-44a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-11-07-11-40-44-sep-2007-11-07-11-40-44a.jpg
deleted file mode 100644
index 916a2b6c3..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2007-11-07-11-40-44-sep-2007-11-07-11-40-44a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-02-10-03-57-sep-2008-06-02-10-03-57a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-02-10-03-57-sep-2008-06-02-10-03-57a.jpg
deleted file mode 100644
index 0aedf3003..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-02-10-03-57-sep-2008-06-02-10-03-57a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-06-13-29-29-sep-2008-06-06-13-29-29a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-06-13-29-29-sep-2008-06-06-13-29-29a.jpg
deleted file mode 100644
index a291900e3..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-06-13-29-29-sep-2008-06-06-13-29-29a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-17-01-21-30-sep-2008-06-17-01-21-30a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-17-01-21-30-sep-2008-06-17-01-21-30a.jpg
deleted file mode 100644
index 805d1d0f0..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-06-17-01-21-30-sep-2008-06-17-01-21-30a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-09-02-17-43-48-sep-2008-09-02-17-43-48a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-09-02-17-43-48-sep-2008-09-02-17-43-48a.jpg
deleted file mode 100644
index c866423c7..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2008-09-02-17-43-48-sep-2008-09-02-17-43-48a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-03-26-09-23-20-sep-2009-03-26-09-23-20a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-03-26-09-23-20-sep-2009-03-26-09-23-20a.jpg
deleted file mode 100644
index 761bf6488..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-03-26-09-23-20-sep-2009-03-26-09-23-20a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-11-03-01-38-sep-2009-04-11-03-01-38a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-11-03-01-38-sep-2009-04-11-03-01-38a.jpg
deleted file mode 100644
index 484fe3759..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-11-03-01-38-sep-2009-04-11-03-01-38a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-23-07-21-35-sep-2009-04-23-07-21-35a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-23-07-21-35-sep-2009-04-23-07-21-35a.jpg
deleted file mode 100644
index f39db7d9a..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-04-23-07-21-35-sep-2009-04-23-07-21-35a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-11-19-23-18-sep-2009-06-11-19-23-18a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-11-19-23-18-sep-2009-06-11-19-23-18a.jpg
deleted file mode 100644
index 599764bf8..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-11-19-23-18-sep-2009-06-11-19-23-18a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-20-07-59-05-sep-2009-06-20-07-59-05a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-20-07-59-05-sep-2009-06-20-07-59-05a.jpg
deleted file mode 100644
index 8718269e9..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-06-20-07-59-05-sep-2009-06-20-07-59-05a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-08-05-08-11-31-sep-2009-08-05-08-11-31a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-08-05-08-11-31-sep-2009-08-05-08-11-31a.jpg
deleted file mode 100644
index 9598b2136..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2009-08-05-08-11-31-sep-2009-08-05-08-11-31a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-08-04-44-24-sep-2010-06-08-04-44-24a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-08-04-44-24-sep-2010-06-08-04-44-24a.jpg
deleted file mode 100644
index 33f7d9b20..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-08-04-44-24-sep-2010-06-08-04-44-24a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-20-20-07-39-sep-2010-06-20-20-07-39a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-20-20-07-39-sep-2010-06-20-20-07-39a.jpg
deleted file mode 100644
index ec2faa1a9..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-06-20-20-07-39-sep-2010-06-20-20-07-39a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-09-02-08-43-02-sep-2010-09-02-08-43-02a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-09-02-08-43-02-sep-2010-09-02-08-43-02a.jpg
deleted file mode 100644
index 3b7f906db..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2010-09-02-08-43-02-sep-2010-09-02-08-43-02a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-01-24-22-06-02-sep-2011-01-24-22-06-02a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-01-24-22-06-02-sep-2011-01-24-22-06-02a.jpg
deleted file mode 100644
index 1a4af42d3..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-01-24-22-06-02-sep-2011-01-24-22-06-02a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-03-07-09-28-03-sep-2011-03-07-09-28-03a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-03-07-09-28-03-sep-2011-03-07-09-28-03a.jpg
deleted file mode 100644
index 42d347656..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-03-07-09-28-03-sep-2011-03-07-09-28-03a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-05-07-13-02-49-sep-2011-05-07-13-02-49a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-05-07-13-02-49-sep-2011-05-07-13-02-49a.jpg
deleted file mode 100644
index 7e84ec481..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-05-07-13-02-49-sep-2011-05-07-13-02-49a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-08-07-19-22-57-sep-2011-08-07-19-22-57a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-08-07-19-22-57-sep-2011-08-07-19-22-57a.jpg
deleted file mode 100644
index 16fad2ecb..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-08-07-19-22-57-sep-2011-08-07-19-22-57a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-17-50-18-sep-2011-10-28-17-50-18a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-17-50-18-sep-2011-10-28-17-50-18a.jpg
deleted file mode 100644
index f6020a8c9..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-17-50-18-sep-2011-10-28-17-50-18a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-18-25-43-sep-2011-10-28-18-25-43.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-18-25-43-sep-2011-10-28-18-25-43.jpg
deleted file mode 100644
index 3aa541878..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-18-25-43-sep-2011-10-28-18-25-43.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-11-18-15-38-34-sep-Photo11181538.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-11-18-15-38-34-sep-Photo11181538.jpg
deleted file mode 100644
index 48ef933a2..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2011-11-18-15-38-34-sep-Photo11181538.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-06-02-10-12-28-sep-2012-06-02-10-12-28.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-06-02-10-12-28-sep-2012-06-02-10-12-28.jpg
deleted file mode 100644
index f83270eee..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-06-02-10-12-28-sep-2012-06-02-10-12-28.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-09-21-22-07-34-sep-2012-09-21-22-07-34.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-09-21-22-07-34-sep-2012-09-21-22-07-34.jpg
deleted file mode 100644
index 5cdb55aac..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-09-21-22-07-34-sep-2012-09-21-22-07-34.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-19-21-38-40-sep-temple_square1.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-19-21-38-40-sep-temple_square1.jpg
deleted file mode 100644
index 4cc074f8e..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-19-21-38-40-sep-temple_square1.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-21-11-15-19-sep-IMG_0001.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-21-11-15-19-sep-IMG_0001.jpg
deleted file mode 100644
index ba23c3c42..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2012-12-21-11-15-19-sep-IMG_0001.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2013-02-05-23-12-09-sep-DSCI0001.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2013-02-05-23-12-09-sep-DSCI0001.jpg
deleted file mode 100644
index 0396148af..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2013-02-05-23-12-09-sep-DSCI0001.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2099-08-12-19-59-29-sep-2099-08-12-19-59-29a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2099-08-12-19-59-29-sep-2099-08-12-19-59-29a.jpg
deleted file mode 100644
index 9729182b3..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2099-08-12-19-59-29-sep-2099-08-12-19-59-29a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2216-11-15-11-46-51-sep-2216-11-15-11-46-51a.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2216-11-15-11-46-51-sep-2216-11-15-11-46-51a.jpg
deleted file mode 100644
index ae53a397a..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/2216-11-15-11-46-51-sep-2216-11-15-11-46-51a.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/FailedHash-NoDate-sep-remembory.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/FailedHash-NoDate-sep-remembory.jpg
deleted file mode 100644
index 9fb415124..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/FailedHash-NoDate-sep-remembory.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f1-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f1-exif.jpg
deleted file mode 100644
index ff003e394..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f1-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f2-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f2-exif.jpg
deleted file mode 100644
index 7e0f170e3..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f2-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f3-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f3-exif.jpg
deleted file mode 100644
index 3ed7b16a7..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f3-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f4-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f4-exif.jpg
deleted file mode 100644
index 0e081f919..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f4-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f5-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f5-exif.jpg
deleted file mode 100644
index e8d875479..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f5-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f6-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f6-exif.jpg
deleted file mode 100644
index 4e2c86415..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f6-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f7-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f7-exif.jpg
deleted file mode 100644
index b5dddea44..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f7-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f8-exif.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f8-exif.jpg
deleted file mode 100644
index fb050fc6d..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/f8-exif.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/geodegrees_as_string.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/geodegrees_as_string.jpg
deleted file mode 100644
index 280a70ec4..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/geodegrees_as_string.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/has-lens-info.jpg b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/has-lens-info.jpg
deleted file mode 100644
index 57757da33..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/exif/samples/has-lens-info.jpg
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/sample1.tif b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/sample1.tif
deleted file mode 100644
index fe51399c5..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/sample1.tif
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tag.go b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tag.go
deleted file mode 100644
index 66b68e334..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tag.go
+++ /dev/null
@@ -1,438 +0,0 @@
-package tiff
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "math/big"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// Format specifies the Go type equivalent used to represent the basic
-// tiff data types.
-type Format int
-
-const (
- IntVal Format = iota
- FloatVal
- RatVal
- StringVal
- UndefVal
- OtherVal
-)
-
-var ErrShortReadTagValue = errors.New("tiff: short read of tag value")
-
-var formatNames = map[Format]string{
- IntVal: "int",
- FloatVal: "float",
- RatVal: "rational",
- StringVal: "string",
- UndefVal: "undefined",
- OtherVal: "other",
-}
-
-// DataType represents the basic tiff tag data types.
-type DataType uint16
-
-const (
- DTByte DataType = 1
- DTAscii = 2
- DTShort = 3
- DTLong = 4
- DTRational = 5
- DTSByte = 6
- DTUndefined = 7
- DTSShort = 8
- DTSLong = 9
- DTSRational = 10
- DTFloat = 11
- DTDouble = 12
-)
-
-var typeNames = map[DataType]string{
- DTByte: "byte",
- DTAscii: "ascii",
- DTShort: "short",
- DTLong: "long",
- DTRational: "rational",
- DTSByte: "signed byte",
- DTUndefined: "undefined",
- DTSShort: "signed short",
- DTSLong: "signed long",
- DTSRational: "signed rational",
- DTFloat: "float",
- DTDouble: "double",
-}
-
-// typeSize specifies the size in bytes of each type.
-var typeSize = map[DataType]uint32{
- DTByte: 1,
- DTAscii: 1,
- DTShort: 2,
- DTLong: 4,
- DTRational: 8,
- DTSByte: 1,
- DTUndefined: 1,
- DTSShort: 2,
- DTSLong: 4,
- DTSRational: 8,
- DTFloat: 4,
- DTDouble: 8,
-}
-
-// Tag reflects the parsed content of a tiff IFD tag.
-type Tag struct {
- // Id is the 2-byte tiff tag identifier.
- Id uint16
- // Type is an integer (1 through 12) indicating the tag value's data type.
- Type DataType
- // Count is the number of type Type stored in the tag's value (i.e. the
- // tag's value is an array of type Type and length Count).
- Count uint32
- // Val holds the bytes that represent the tag's value.
- Val []byte
- // ValOffset holds byte offset of the tag value w.r.t. the beginning of the
- // reader it was decoded from. Zero if the tag value fit inside the offset
- // field.
- ValOffset uint32
-
- order binary.ByteOrder
- intVals []int64
- floatVals []float64
- ratVals [][]int64
- strVal string
- format Format
-}
-
-// DecodeTag parses a tiff-encoded IFD tag from r and returns a Tag object. The
-// first read from r should be the first byte of the tag. ReadAt offsets should
-// generally be relative to the beginning of the tiff structure (not relative
-// to the beginning of the tag).
-func DecodeTag(r ReadAtReader, order binary.ByteOrder) (*Tag, error) {
- t := new(Tag)
- t.order = order
-
- err := binary.Read(r, order, &t.Id)
- if err != nil {
- return nil, errors.New("tiff: tag id read failed: " + err.Error())
- }
-
- err = binary.Read(r, order, &t.Type)
- if err != nil {
- return nil, errors.New("tiff: tag type read failed: " + err.Error())
- }
-
- err = binary.Read(r, order, &t.Count)
- if err != nil {
- return nil, errors.New("tiff: tag component count read failed: " + err.Error())
- }
-
- // There seems to be a relatively common corrupt tag which has a Count of
- // MaxUint32. This is probably not a valid value, so return early.
- if t.Count == 1<<32-1 {
- return t, errors.New("invalid Count offset in tag")
- }
-
- valLen := typeSize[t.Type] * t.Count
- if valLen == 0 {
- return t, errors.New("zero length tag value")
- }
-
- if valLen > 4 {
- binary.Read(r, order, &t.ValOffset)
-
- // Use a bytes.Buffer so we don't allocate a huge slice if the tag
- // is corrupt.
- var buff bytes.Buffer
- sr := io.NewSectionReader(r, int64(t.ValOffset), int64(valLen))
- n, err := io.Copy(&buff, sr)
- if err != nil {
- return t, errors.New("tiff: tag value read failed: " + err.Error())
- } else if n != int64(valLen) {
- return t, ErrShortReadTagValue
- }
- t.Val = buff.Bytes()
-
- } else {
- val := make([]byte, valLen)
- if _, err = io.ReadFull(r, val); err != nil {
- return t, errors.New("tiff: tag offset read failed: " + err.Error())
- }
- // ignore padding.
- if _, err = io.ReadFull(r, make([]byte, 4-valLen)); err != nil {
- return t, errors.New("tiff: tag offset read failed: " + err.Error())
- }
-
- t.Val = val
- }
-
- return t, t.convertVals()
-}
-
-func (t *Tag) convertVals() error {
- r := bytes.NewReader(t.Val)
-
- switch t.Type {
- case DTAscii:
- if len(t.Val) > 0 {
- t.strVal = string(t.Val[:len(t.Val)-1]) // ignore the last byte (NULL).
- }
- case DTByte:
- var v uint8
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTShort:
- var v uint16
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTLong:
- var v uint32
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTSByte:
- var v int8
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTSShort:
- var v int16
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTSLong:
- var v int32
- t.intVals = make([]int64, int(t.Count))
- for i := range t.intVals {
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.intVals[i] = int64(v)
- }
- case DTRational:
- t.ratVals = make([][]int64, int(t.Count))
- for i := range t.ratVals {
- var n, d uint32
- err := binary.Read(r, t.order, &n)
- if err != nil {
- return err
- }
- err = binary.Read(r, t.order, &d)
- if err != nil {
- return err
- }
- t.ratVals[i] = []int64{int64(n), int64(d)}
- }
- case DTSRational:
- t.ratVals = make([][]int64, int(t.Count))
- for i := range t.ratVals {
- var n, d int32
- err := binary.Read(r, t.order, &n)
- if err != nil {
- return err
- }
- err = binary.Read(r, t.order, &d)
- if err != nil {
- return err
- }
- t.ratVals[i] = []int64{int64(n), int64(d)}
- }
- case DTFloat: // float32
- t.floatVals = make([]float64, int(t.Count))
- for i := range t.floatVals {
- var v float32
- err := binary.Read(r, t.order, &v)
- if err != nil {
- return err
- }
- t.floatVals[i] = float64(v)
- }
- case DTDouble:
- t.floatVals = make([]float64, int(t.Count))
- for i := range t.floatVals {
- var u float64
- err := binary.Read(r, t.order, &u)
- if err != nil {
- return err
- }
- t.floatVals[i] = u
- }
- }
-
- switch t.Type {
- case DTByte, DTShort, DTLong, DTSByte, DTSShort, DTSLong:
- t.format = IntVal
- case DTRational, DTSRational:
- t.format = RatVal
- case DTFloat, DTDouble:
- t.format = FloatVal
- case DTAscii:
- t.format = StringVal
- case DTUndefined:
- t.format = UndefVal
- default:
- t.format = OtherVal
- }
-
- return nil
-}
-
-// Format returns a value indicating which method can be called to retrieve the
-// tag's value properly typed (e.g. integer, rational, etc.).
-func (t *Tag) Format() Format { return t.format }
-
-func (t *Tag) typeErr(to Format) error {
- return &wrongFmtErr{typeNames[t.Type], formatNames[to]}
-}
-
-// Rat returns the tag's i'th value as a rational number. It returns a nil and
-// an error if this tag's Format is not RatVal. It panics for zero deminators
-// or if i is out of range.
-func (t *Tag) Rat(i int) (*big.Rat, error) {
- n, d, err := t.Rat2(i)
- if err != nil {
- return nil, err
- }
- return big.NewRat(n, d), nil
-}
-
-// Rat2 returns the tag's i'th value as a rational number represented by a
-// numerator-denominator pair. It returns an error if the tag's Format is not
-// RatVal. It panics if i is out of range.
-func (t *Tag) Rat2(i int) (num, den int64, err error) {
- if t.format != RatVal {
- return 0, 0, t.typeErr(RatVal)
- }
- return t.ratVals[i][0], t.ratVals[i][1], nil
-}
-
-// Int64 returns the tag's i'th value as an integer. It returns an error if the
-// tag's Format is not IntVal. It panics if i is out of range.
-func (t *Tag) Int64(i int) (int64, error) {
- if t.format != IntVal {
- return 0, t.typeErr(IntVal)
- }
- return t.intVals[i], nil
-}
-
-// Int returns the tag's i'th value as an integer. It returns an error if the
-// tag's Format is not IntVal. It panics if i is out of range.
-func (t *Tag) Int(i int) (int, error) {
- if t.format != IntVal {
- return 0, t.typeErr(IntVal)
- }
- return int(t.intVals[i]), nil
-}
-
-// Float returns the tag's i'th value as a float. It returns an error if the
-// tag's Format is not IntVal. It panics if i is out of range.
-func (t *Tag) Float(i int) (float64, error) {
- if t.format != FloatVal {
- return 0, t.typeErr(FloatVal)
- }
- return t.floatVals[i], nil
-}
-
-// StringVal returns the tag's value as a string. It returns an error if the
-// tag's Format is not StringVal. It panics if i is out of range.
-func (t *Tag) StringVal() (string, error) {
- if t.format != StringVal {
- return "", t.typeErr(StringVal)
- }
- return t.strVal, nil
-}
-
-// String returns a nicely formatted version of the tag.
-func (t *Tag) String() string {
- data, err := t.MarshalJSON()
- if err != nil {
- return "ERROR: " + err.Error()
- }
-
- if t.Count == 1 {
- return strings.Trim(fmt.Sprintf("%s", data), "[]")
- }
- return fmt.Sprintf("%s", data)
-}
-
-func (t *Tag) MarshalJSON() ([]byte, error) {
- switch t.format {
- case StringVal, UndefVal:
- return nullString(t.Val), nil
- case OtherVal:
- return []byte(fmt.Sprintf("unknown tag type '%v'", t.Type)), nil
- }
-
- rv := []string{}
- for i := 0; i < int(t.Count); i++ {
- switch t.format {
- case RatVal:
- n, d, _ := t.Rat2(i)
- rv = append(rv, fmt.Sprintf(`"%v/%v"`, n, d))
- case FloatVal:
- v, _ := t.Float(i)
- rv = append(rv, fmt.Sprintf("%v", v))
- case IntVal:
- v, _ := t.Int(i)
- rv = append(rv, fmt.Sprintf("%v", v))
- }
- }
- return []byte(fmt.Sprintf(`[%s]`, strings.Join(rv, ","))), nil
-}
-
-func nullString(in []byte) []byte {
- rv := bytes.Buffer{}
- rv.WriteByte('"')
- for _, b := range in {
- if unicode.IsPrint(rune(b)) {
- rv.WriteByte(b)
- }
- }
- rv.WriteByte('"')
- rvb := rv.Bytes()
- if utf8.Valid(rvb) {
- return rvb
- }
- return []byte(`""`)
-}
-
-type wrongFmtErr struct {
- From, To string
-}
-
-func (e *wrongFmtErr) Error() string {
- return fmt.Sprintf("cannot convert tag type '%v' into '%v'", e.From, e.To)
-}
diff --git a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tiff.go b/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tiff.go
deleted file mode 100644
index 771e91878..000000000
--- a/Godeps/_workspace/src/github.com/rwcarlsen/goexif/tiff/tiff.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Package tiff implements TIFF decoding as defined in TIFF 6.0 specification at
-// http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
-package tiff
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
-)
-
-// ReadAtReader is used when decoding Tiff tags and directories
-type ReadAtReader interface {
- io.Reader
- io.ReaderAt
-}
-
-// Tiff provides access to a decoded tiff data structure.
-type Tiff struct {
- // Dirs is an ordered slice of the tiff's Image File Directories (IFDs).
- // The IFD at index 0 is IFD0.
- Dirs []*Dir
- // The tiff's byte-encoding (i.e. big/little endian).
- Order binary.ByteOrder
-}
-
-// Decode parses tiff-encoded data from r and returns a Tiff struct that
-// reflects the structure and content of the tiff data. The first read from r
-// should be the first byte of the tiff-encoded data and not necessarily the
-// first byte of an os.File object.
-func Decode(r io.Reader) (*Tiff, error) {
- data, err := ioutil.ReadAll(r)
- if err != nil {
- return nil, errors.New("tiff: could not read data")
- }
- buf := bytes.NewReader(data)
-
- t := new(Tiff)
-
- // read byte order
- bo := make([]byte, 2)
- if _, err = io.ReadFull(buf, bo); err != nil {
- return nil, errors.New("tiff: could not read tiff byte order")
- }
- if string(bo) == "II" {
- t.Order = binary.LittleEndian
- } else if string(bo) == "MM" {
- t.Order = binary.BigEndian
- } else {
- return nil, errors.New("tiff: could not read tiff byte order")
- }
-
- // check for special tiff marker
- var sp int16
- err = binary.Read(buf, t.Order, &sp)
- if err != nil || 42 != sp {
- return nil, errors.New("tiff: could not find special tiff marker")
- }
-
- // load offset to first IFD
- var offset int32
- err = binary.Read(buf, t.Order, &offset)
- if err != nil {
- return nil, errors.New("tiff: could not read offset to first IFD")
- }
-
- // load IFD's
- var d *Dir
- prev := offset
- for offset != 0 {
- // seek to offset
- _, err := buf.Seek(int64(offset), 0)
- if err != nil {
- return nil, errors.New("tiff: seek to IFD failed")
- }
-
- if buf.Len() == 0 {
- return nil, errors.New("tiff: seek offset after EOF")
- }
-
- // load the dir
- d, offset, err = DecodeDir(buf, t.Order)
- if err != nil {
- return nil, err
- }
-
- if offset == prev {
- return nil, errors.New("tiff: recursive IFD")
- }
- prev = offset
-
- t.Dirs = append(t.Dirs, d)
- }
-
- return t, nil
-}
-
-func (tf *Tiff) String() string {
- var buf bytes.Buffer
- fmt.Fprint(&buf, "Tiff{")
- for _, d := range tf.Dirs {
- fmt.Fprintf(&buf, "%s, ", d.String())
- }
- fmt.Fprintf(&buf, "}")
- return buf.String()
-}
-
-// Dir provides access to the parsed content of a tiff Image File Directory (IFD).
-type Dir struct {
- Tags []*Tag
-}
-
-// DecodeDir parses a tiff-encoded IFD from r and returns a Dir object. offset
-// is the offset to the next IFD. The first read from r should be at the first
-// byte of the IFD. ReadAt offsets should generally be relative to the
-// beginning of the tiff structure (not relative to the beginning of the IFD).
-func DecodeDir(r ReadAtReader, order binary.ByteOrder) (d *Dir, offset int32, err error) {
- d = new(Dir)
-
- // get num of tags in ifd
- var nTags int16
- err = binary.Read(r, order, &nTags)
- if err != nil {
- return nil, 0, errors.New("tiff: failed to read IFD tag count: " + err.Error())
- }
-
- // load tags
- for n := 0; n < int(nTags); n++ {
- t, err := DecodeTag(r, order)
- if err != nil {
- return nil, 0, err
- }
- d.Tags = append(d.Tags, t)
- }
-
- // get offset to next ifd
- err = binary.Read(r, order, &offset)
- if err != nil {
- return nil, 0, errors.New("tiff: falied to read offset to next IFD: " + err.Error())
- }
-
- return d, offset, nil
-}
-
-func (d *Dir) String() string {
- s := "Dir{"
- for _, t := range d.Tags {
- s += t.String() + ", "
- }
- return s + "}"
-}
diff --git a/Godeps/_workspace/src/github.com/vaughan0/go-ini/LICENSE b/Godeps/_workspace/src/github.com/vaughan0/go-ini/LICENSE
deleted file mode 100644
index 968b45384..000000000
--- a/Godeps/_workspace/src/github.com/vaughan0/go-ini/LICENSE
+++ /dev/null
@@ -1,14 +0,0 @@
-Copyright (c) 2013 Vaughan Newton
-
-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.
diff --git a/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md b/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md
deleted file mode 100644
index d5cd4e74b..000000000
--- a/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md
+++ /dev/null
@@ -1,70 +0,0 @@
-go-ini
-======
-
-INI parsing library for Go (golang).
-
-View the API documentation [here](http://godoc.org/github.com/vaughan0/go-ini).
-
-Usage
------
-
-Parse an INI file:
-
-```go
-import "github.com/vaughan0/go-ini"
-
-file, err := ini.LoadFile("myfile.ini")
-```
-
-Get data from the parsed file:
-
-```go
-name, ok := file.Get("person", "name")
-if !ok {
- panic("'name' variable missing from 'person' section")
-}
-```
-
-Iterate through values in a section:
-
-```go
-for key, value := range file["mysection"] {
- fmt.Printf("%s => %s\n", key, value)
-}
-```
-
-Iterate through sections in a file:
-
-```go
-for name, section := range file {
- fmt.Printf("Section name: %s\n", name)
-}
-```
-
-File Format
------------
-
-INI files are parsed by go-ini line-by-line. Each line may be one of the following:
-
- * A section definition: [section-name]
- * A property: key = value
- * A comment: #blahblah _or_ ;blahblah
- * Blank. The line will be ignored.
-
-Properties defined before any section headers are placed in the default section, which has
-the empty string as it's key.
-
-Example:
-
-```ini
-# I am a comment
-; So am I!
-
-[apples]
-colour = red or green
-shape = applish
-
-[oranges]
-shape = square
-colour = blue
-```
diff --git a/Godeps/_workspace/src/github.com/vaughan0/go-ini/ini.go b/Godeps/_workspace/src/github.com/vaughan0/go-ini/ini.go
deleted file mode 100644
index 81aeb32f8..000000000
--- a/Godeps/_workspace/src/github.com/vaughan0/go-ini/ini.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Package ini provides functions for parsing INI configuration files.
-package ini
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- sectionRegex = regexp.MustCompile(`^\[(.*)\]$`)
- assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
-)
-
-// ErrSyntax is returned when there is a syntax error in an INI file.
-type ErrSyntax struct {
- Line int
- Source string // The contents of the erroneous line, without leading or trailing whitespace
-}
-
-func (e ErrSyntax) Error() string {
- return fmt.Sprintf("invalid INI syntax on line %d: %s", e.Line, e.Source)
-}
-
-// A File represents a parsed INI file.
-type File map[string]Section
-
-// A Section represents a single section of an INI file.
-type Section map[string]string
-
-// Returns a named Section. A Section will be created if one does not already exist for the given name.
-func (f File) Section(name string) Section {
- section := f[name]
- if section == nil {
- section = make(Section)
- f[name] = section
- }
- return section
-}
-
-// Looks up a value for a key in a section and returns that value, along with a boolean result similar to a map lookup.
-func (f File) Get(section, key string) (value string, ok bool) {
- if s := f[section]; s != nil {
- value, ok = s[key]
- }
- return
-}
-
-// Loads INI data from a reader and stores the data in the File.
-func (f File) Load(in io.Reader) (err error) {
- bufin, ok := in.(*bufio.Reader)
- if !ok {
- bufin = bufio.NewReader(in)
- }
- return parseFile(bufin, f)
-}
-
-// Loads INI data from a named file and stores the data in the File.
-func (f File) LoadFile(file string) (err error) {
- in, err := os.Open(file)
- if err != nil {
- return
- }
- defer in.Close()
- return f.Load(in)
-}
-
-func parseFile(in *bufio.Reader, file File) (err error) {
- section := ""
- lineNum := 0
- for done := false; !done; {
- var line string
- if line, err = in.ReadString('\n'); err != nil {
- if err == io.EOF {
- done = true
- } else {
- return
- }
- }
- lineNum++
- line = strings.TrimSpace(line)
- if len(line) == 0 {
- // Skip blank lines
- continue
- }
- if line[0] == ';' || line[0] == '#' {
- // Skip comments
- continue
- }
-
- if groups := assignRegex.FindStringSubmatch(line); groups != nil {
- key, val := groups[1], groups[2]
- key, val = strings.TrimSpace(key), strings.TrimSpace(val)
- file.Section(section)[key] = val
- } else if groups := sectionRegex.FindStringSubmatch(line); groups != nil {
- name := strings.TrimSpace(groups[1])
- section = name
- // Create the section if it does not exist
- file.Section(section)
- } else {
- return ErrSyntax{lineNum, line}
- }
-
- }
- return nil
-}
-
-// Loads and returns a File from a reader.
-func Load(in io.Reader) (File, error) {
- file := make(File)
- err := file.Load(in)
- return file, err
-}
-
-// Loads and returns an INI File from a file on disk.
-func LoadFile(filename string) (File, error) {
- file := make(File)
- err := file.LoadFile(filename)
- return file, err
-}
diff --git a/Godeps/_workspace/src/github.com/vaughan0/go-ini/test.ini b/Godeps/_workspace/src/github.com/vaughan0/go-ini/test.ini
deleted file mode 100644
index d13c999e2..000000000
--- a/Godeps/_workspace/src/github.com/vaughan0/go-ini/test.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[default]
-stuff = things
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/LICENSE b/Godeps/_workspace/src/golang.org/x/crypto/LICENSE
deleted file mode 100644
index 6a66aea5e..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/PATENTS b/Godeps/_workspace/src/golang.org/x/crypto/PATENTS
deleted file mode 100644
index 733099041..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go b/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go
deleted file mode 100644
index fc3116090..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bcrypt
-
-import "encoding/base64"
-
-const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
-
-var bcEncoding = base64.NewEncoding(alphabet)
-
-func base64Encode(src []byte) []byte {
- n := bcEncoding.EncodedLen(len(src))
- dst := make([]byte, n)
- bcEncoding.Encode(dst, src)
- for dst[n-1] == '=' {
- n--
- }
- return dst[:n]
-}
-
-func base64Decode(src []byte) ([]byte, error) {
- numOfEquals := 4 - (len(src) % 4)
- for i := 0; i < numOfEquals; i++ {
- src = append(src, '=')
- }
-
- dst := make([]byte, bcEncoding.DecodedLen(len(src)))
- n, err := bcEncoding.Decode(dst, src)
- if err != nil {
- return nil, err
- }
- return dst[:n], nil
-}
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go b/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go
deleted file mode 100644
index b8e18d744..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
-// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
-package bcrypt
-
-// The code is a port of Provos and Mazières's C implementation.
-import (
- "crypto/rand"
- "crypto/subtle"
- "errors"
- "fmt"
- "golang.org/x/crypto/blowfish"
- "io"
- "strconv"
-)
-
-const (
- MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
- MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
- DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
-)
-
-// The error returned from CompareHashAndPassword when a password and hash do
-// not match.
-var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
-
-// The error returned from CompareHashAndPassword when a hash is too short to
-// be a bcrypt hash.
-var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
-
-// The error returned from CompareHashAndPassword when a hash was created with
-// a bcrypt algorithm newer than this implementation.
-type HashVersionTooNewError byte
-
-func (hv HashVersionTooNewError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
-}
-
-// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
-type InvalidHashPrefixError byte
-
-func (ih InvalidHashPrefixError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
-}
-
-type InvalidCostError int
-
-func (ic InvalidCostError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
-}
-
-const (
- majorVersion = '2'
- minorVersion = 'a'
- maxSaltSize = 16
- maxCryptedHashSize = 23
- encodedSaltSize = 22
- encodedHashSize = 31
- minHashSize = 59
-)
-
-// magicCipherData is an IV for the 64 Blowfish encryption calls in
-// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
-var magicCipherData = []byte{
- 0x4f, 0x72, 0x70, 0x68,
- 0x65, 0x61, 0x6e, 0x42,
- 0x65, 0x68, 0x6f, 0x6c,
- 0x64, 0x65, 0x72, 0x53,
- 0x63, 0x72, 0x79, 0x44,
- 0x6f, 0x75, 0x62, 0x74,
-}
-
-type hashed struct {
- hash []byte
- salt []byte
- cost int // allowed range is MinCost to MaxCost
- major byte
- minor byte
-}
-
-// GenerateFromPassword returns the bcrypt hash of the password at the given
-// cost. If the cost given is less than MinCost, the cost will be set to
-// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
-// to compare the returned hashed password with its cleartext version.
-func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
- p, err := newFromPassword(password, cost)
- if err != nil {
- return nil, err
- }
- return p.Hash(), nil
-}
-
-// CompareHashAndPassword compares a bcrypt hashed password with its possible
-// plaintext equivalent. Returns nil on success, or an error on failure.
-func CompareHashAndPassword(hashedPassword, password []byte) error {
- p, err := newFromHash(hashedPassword)
- if err != nil {
- return err
- }
-
- otherHash, err := bcrypt(password, p.cost, p.salt)
- if err != nil {
- return err
- }
-
- otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
- if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
- return nil
- }
-
- return ErrMismatchedHashAndPassword
-}
-
-// Cost returns the hashing cost used to create the given hashed
-// password. When, in the future, the hashing cost of a password system needs
-// to be increased in order to adjust for greater computational power, this
-// function allows one to establish which passwords need to be updated.
-func Cost(hashedPassword []byte) (int, error) {
- p, err := newFromHash(hashedPassword)
- if err != nil {
- return 0, err
- }
- return p.cost, nil
-}
-
-func newFromPassword(password []byte, cost int) (*hashed, error) {
- if cost < MinCost {
- cost = DefaultCost
- }
- p := new(hashed)
- p.major = majorVersion
- p.minor = minorVersion
-
- err := checkCost(cost)
- if err != nil {
- return nil, err
- }
- p.cost = cost
-
- unencodedSalt := make([]byte, maxSaltSize)
- _, err = io.ReadFull(rand.Reader, unencodedSalt)
- if err != nil {
- return nil, err
- }
-
- p.salt = base64Encode(unencodedSalt)
- hash, err := bcrypt(password, p.cost, p.salt)
- if err != nil {
- return nil, err
- }
- p.hash = hash
- return p, err
-}
-
-func newFromHash(hashedSecret []byte) (*hashed, error) {
- if len(hashedSecret) < minHashSize {
- return nil, ErrHashTooShort
- }
- p := new(hashed)
- n, err := p.decodeVersion(hashedSecret)
- if err != nil {
- return nil, err
- }
- hashedSecret = hashedSecret[n:]
- n, err = p.decodeCost(hashedSecret)
- if err != nil {
- return nil, err
- }
- hashedSecret = hashedSecret[n:]
-
- // The "+2" is here because we'll have to append at most 2 '=' to the salt
- // when base64 decoding it in expensiveBlowfishSetup().
- p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
- copy(p.salt, hashedSecret[:encodedSaltSize])
-
- hashedSecret = hashedSecret[encodedSaltSize:]
- p.hash = make([]byte, len(hashedSecret))
- copy(p.hash, hashedSecret)
-
- return p, nil
-}
-
-func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
- cipherData := make([]byte, len(magicCipherData))
- copy(cipherData, magicCipherData)
-
- c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
- if err != nil {
- return nil, err
- }
-
- for i := 0; i < 24; i += 8 {
- for j := 0; j < 64; j++ {
- c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
- }
- }
-
- // Bug compatibility with C bcrypt implementations. We only encode 23 of
- // the 24 bytes encrypted.
- hsh := base64Encode(cipherData[:maxCryptedHashSize])
- return hsh, nil
-}
-
-func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
-
- csalt, err := base64Decode(salt)
- if err != nil {
- return nil, err
- }
-
- // Bug compatibility with C bcrypt implementations. They use the trailing
- // NULL in the key string during expansion.
- ckey := append(key, 0)
-
- c, err := blowfish.NewSaltedCipher(ckey, csalt)
- if err != nil {
- return nil, err
- }
-
- var i, rounds uint64
- rounds = 1 << cost
- for i = 0; i < rounds; i++ {
- blowfish.ExpandKey(ckey, c)
- blowfish.ExpandKey(csalt, c)
- }
-
- return c, nil
-}
-
-func (p *hashed) Hash() []byte {
- arr := make([]byte, 60)
- arr[0] = '$'
- arr[1] = p.major
- n := 2
- if p.minor != 0 {
- arr[2] = p.minor
- n = 3
- }
- arr[n] = '$'
- n += 1
- copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
- n += 2
- arr[n] = '$'
- n += 1
- copy(arr[n:], p.salt)
- n += encodedSaltSize
- copy(arr[n:], p.hash)
- n += encodedHashSize
- return arr[:n]
-}
-
-func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
- if sbytes[0] != '$' {
- return -1, InvalidHashPrefixError(sbytes[0])
- }
- if sbytes[1] > majorVersion {
- return -1, HashVersionTooNewError(sbytes[1])
- }
- p.major = sbytes[1]
- n := 3
- if sbytes[2] != '$' {
- p.minor = sbytes[2]
- n++
- }
- return n, nil
-}
-
-// sbytes should begin where decodeVersion left off.
-func (p *hashed) decodeCost(sbytes []byte) (int, error) {
- cost, err := strconv.Atoi(string(sbytes[0:2]))
- if err != nil {
- return -1, err
- }
- err = checkCost(cost)
- if err != nil {
- return -1, err
- }
- p.cost = cost
- return 3, nil
-}
-
-func (p *hashed) String() string {
- return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
-}
-
-func checkCost(cost int) error {
- if cost < MinCost || cost > MaxCost {
- return InvalidCostError(cost)
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go b/Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go
deleted file mode 100644
index 9d80f1952..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package blowfish
-
-// getNextWord returns the next big-endian uint32 value from the byte slice
-// at the given position in a circular manner, updating the position.
-func getNextWord(b []byte, pos *int) uint32 {
- var w uint32
- j := *pos
- for i := 0; i < 4; i++ {
- w = w<<8 | uint32(b[j])
- j++
- if j >= len(b) {
- j = 0
- }
- }
- *pos = j
- return w
-}
-
-// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
-// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
-// pi and substitution tables for calls to Encrypt. This is used, primarily,
-// by the bcrypt package to reuse the Blowfish key schedule during its
-// set up. It's unlikely that you need to use this directly.
-func ExpandKey(key []byte, c *Cipher) {
- j := 0
- for i := 0; i < 18; i++ {
- // Using inlined getNextWord for performance.
- var d uint32
- for k := 0; k < 4; k++ {
- d = d<<8 | uint32(key[j])
- j++
- if j >= len(key) {
- j = 0
- }
- }
- c.p[i] ^= d
- }
-
- var l, r uint32
- for i := 0; i < 18; i += 2 {
- l, r = encryptBlock(l, r, c)
- c.p[i], c.p[i+1] = l, r
- }
-
- for i := 0; i < 256; i += 2 {
- l, r = encryptBlock(l, r, c)
- c.s0[i], c.s0[i+1] = l, r
- }
- for i := 0; i < 256; i += 2 {
- l, r = encryptBlock(l, r, c)
- c.s1[i], c.s1[i+1] = l, r
- }
- for i := 0; i < 256; i += 2 {
- l, r = encryptBlock(l, r, c)
- c.s2[i], c.s2[i+1] = l, r
- }
- for i := 0; i < 256; i += 2 {
- l, r = encryptBlock(l, r, c)
- c.s3[i], c.s3[i+1] = l, r
- }
-}
-
-// This is similar to ExpandKey, but folds the salt during the key
-// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
-// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
-// and specializing it here is useful.
-func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
- j := 0
- for i := 0; i < 18; i++ {
- c.p[i] ^= getNextWord(key, &j)
- }
-
- j = 0
- var l, r uint32
- for i := 0; i < 18; i += 2 {
- l ^= getNextWord(salt, &j)
- r ^= getNextWord(salt, &j)
- l, r = encryptBlock(l, r, c)
- c.p[i], c.p[i+1] = l, r
- }
-
- for i := 0; i < 256; i += 2 {
- l ^= getNextWord(salt, &j)
- r ^= getNextWord(salt, &j)
- l, r = encryptBlock(l, r, c)
- c.s0[i], c.s0[i+1] = l, r
- }
-
- for i := 0; i < 256; i += 2 {
- l ^= getNextWord(salt, &j)
- r ^= getNextWord(salt, &j)
- l, r = encryptBlock(l, r, c)
- c.s1[i], c.s1[i+1] = l, r
- }
-
- for i := 0; i < 256; i += 2 {
- l ^= getNextWord(salt, &j)
- r ^= getNextWord(salt, &j)
- l, r = encryptBlock(l, r, c)
- c.s2[i], c.s2[i+1] = l, r
- }
-
- for i := 0; i < 256; i += 2 {
- l ^= getNextWord(salt, &j)
- r ^= getNextWord(salt, &j)
- l, r = encryptBlock(l, r, c)
- c.s3[i], c.s3[i+1] = l, r
- }
-}
-
-func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
- xl, xr := l, r
- xl ^= c.p[0]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
- xr ^= c.p[17]
- return xr, xl
-}
-
-func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
- xl, xr := l, r
- xl ^= c.p[17]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
- xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
- xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
- xr ^= c.p[0]
- return xr, xl
-}
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go b/Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go
deleted file mode 100644
index 5019658a4..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
-package blowfish
-
-// The code is a port of Bruce Schneier's C implementation.
-// See http://www.schneier.com/blowfish.html.
-
-import "strconv"
-
-// The Blowfish block size in bytes.
-const BlockSize = 8
-
-// A Cipher is an instance of Blowfish encryption using a particular key.
-type Cipher struct {
- p [18]uint32
- s0, s1, s2, s3 [256]uint32
-}
-
-type KeySizeError int
-
-func (k KeySizeError) Error() string {
- return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
-}
-
-// NewCipher creates and returns a Cipher.
-// The key argument should be the Blowfish key, from 1 to 56 bytes.
-func NewCipher(key []byte) (*Cipher, error) {
- var result Cipher
- if k := len(key); k < 1 || k > 56 {
- return nil, KeySizeError(k)
- }
- initCipher(&result)
- ExpandKey(key, &result)
- return &result, nil
-}
-
-// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
-// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
-// sufficient and desirable. For bcrypt compatiblity, the key can be over 56
-// bytes.
-func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
- if len(salt) == 0 {
- return NewCipher(key)
- }
- var result Cipher
- if k := len(key); k < 1 {
- return nil, KeySizeError(k)
- }
- initCipher(&result)
- expandKeyWithSalt(key, salt, &result)
- return &result, nil
-}
-
-// BlockSize returns the Blowfish block size, 8 bytes.
-// It is necessary to satisfy the Block interface in the
-// package "crypto/cipher".
-func (c *Cipher) BlockSize() int { return BlockSize }
-
-// Encrypt encrypts the 8-byte buffer src using the key k
-// and stores the result in dst.
-// Note that for amounts of data larger than a block,
-// it is not safe to just call Encrypt on successive blocks;
-// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
-func (c *Cipher) Encrypt(dst, src []byte) {
- l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
- r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
- l, r = encryptBlock(l, r, c)
- dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
- dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
-}
-
-// Decrypt decrypts the 8-byte buffer src using the key k
-// and stores the result in dst.
-func (c *Cipher) Decrypt(dst, src []byte) {
- l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
- r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
- l, r = decryptBlock(l, r, c)
- dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
- dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
-}
-
-func initCipher(c *Cipher) {
- copy(c.p[0:], p[0:])
- copy(c.s0[0:], s0[0:])
- copy(c.s1[0:], s1[0:])
- copy(c.s2[0:], s2[0:])
- copy(c.s3[0:], s3[0:])
-}
diff --git a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go b/Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go
deleted file mode 100644
index 8c5ee4cb0..000000000
--- a/Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The startup permutation array and substitution boxes.
-// They are the hexadecimal digits of PI; see:
-// http://www.schneier.com/code/constants.txt.
-
-package blowfish
-
-var s0 = [256]uint32{
- 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
- 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
- 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
- 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
- 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
- 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
- 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
- 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
- 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
- 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
- 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
- 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
- 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
- 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
- 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
- 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
- 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
- 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
- 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
- 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
- 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
- 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
- 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
- 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
- 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
- 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
- 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
- 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
- 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
- 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
- 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
- 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
- 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
- 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
- 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
- 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
- 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
- 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
- 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
- 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
- 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
- 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
- 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
-}
-
-var s1 = [256]uint32{
- 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
- 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
- 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
- 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
- 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
- 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
- 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
- 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
- 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
- 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
- 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
- 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
- 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
- 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
- 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
- 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
- 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
- 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
- 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
- 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
- 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
- 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
- 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
- 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
- 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
- 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
- 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
- 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
- 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
- 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
- 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
- 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
- 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
- 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
- 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
- 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
- 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
- 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
- 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
- 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
- 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
- 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
- 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
-}
-
-var s2 = [256]uint32{
- 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
- 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
- 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
- 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
- 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
- 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
- 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
- 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
- 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
- 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
- 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
- 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
- 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
- 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
- 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
- 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
- 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
- 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
- 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
- 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
- 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
- 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
- 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
- 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
- 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
- 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
- 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
- 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
- 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
- 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
- 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
- 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
- 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
- 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
- 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
- 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
- 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
- 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
- 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
- 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
- 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
- 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
- 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
-}
-
-var s3 = [256]uint32{
- 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
- 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
- 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
- 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
- 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
- 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
- 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
- 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
- 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
- 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
- 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
- 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
- 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
- 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
- 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
- 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
- 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
- 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
- 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
- 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
- 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
- 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
- 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
- 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
- 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
- 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
- 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
- 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
- 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
- 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
- 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
- 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
- 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
- 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
- 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
- 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
- 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
- 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
- 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
- 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
- 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
- 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
- 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
-}
-
-var p = [18]uint32{
- 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
- 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
- 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/LICENSE b/Godeps/_workspace/src/golang.org/x/image/LICENSE
deleted file mode 100644
index 6a66aea5e..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/golang.org/x/image/PATENTS b/Godeps/_workspace/src/golang.org/x/image/PATENTS
deleted file mode 100644
index 733099041..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/Godeps/_workspace/src/golang.org/x/image/bmp/reader.go b/Godeps/_workspace/src/golang.org/x/image/bmp/reader.go
deleted file mode 100644
index a48cba84d..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/bmp/reader.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bmp implements a BMP image decoder and encoder.
-//
-// The BMP specification is at http://www.digicamsoft.com/bmp/bmp.html.
-package bmp
-
-import (
- "errors"
- "image"
- "image/color"
- "io"
-)
-
-// ErrUnsupported means that the input BMP image uses a valid but unsupported
-// feature.
-var ErrUnsupported = errors.New("bmp: unsupported BMP image")
-
-func readUint16(b []byte) uint16 {
- return uint16(b[0]) | uint16(b[1])<<8
-}
-
-func readUint32(b []byte) uint32 {
- return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-}
-
-// decodePaletted reads an 8 bit-per-pixel BMP image from r.
-// If topDown is false, the image rows will be read bottom-up.
-func decodePaletted(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
- paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette))
- if c.Width == 0 || c.Height == 0 {
- return paletted, nil
- }
- var tmp [4]byte
- y0, y1, yDelta := c.Height-1, -1, -1
- if topDown {
- y0, y1, yDelta = 0, c.Height, +1
- }
- for y := y0; y != y1; y += yDelta {
- p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width]
- if _, err := io.ReadFull(r, p); err != nil {
- return nil, err
- }
- // Each row is 4-byte aligned.
- if c.Width%4 != 0 {
- _, err := io.ReadFull(r, tmp[:4-c.Width%4])
- if err != nil {
- return nil, err
- }
- }
- }
- return paletted, nil
-}
-
-// decodeRGB reads a 24 bit-per-pixel BMP image from r.
-// If topDown is false, the image rows will be read bottom-up.
-func decodeRGB(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
- rgba := image.NewRGBA(image.Rect(0, 0, c.Width, c.Height))
- if c.Width == 0 || c.Height == 0 {
- return rgba, nil
- }
- // There are 3 bytes per pixel, and each row is 4-byte aligned.
- b := make([]byte, (3*c.Width+3)&^3)
- y0, y1, yDelta := c.Height-1, -1, -1
- if topDown {
- y0, y1, yDelta = 0, c.Height, +1
- }
- for y := y0; y != y1; y += yDelta {
- if _, err := io.ReadFull(r, b); err != nil {
- return nil, err
- }
- p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
- for i, j := 0, 0; i < len(p); i, j = i+4, j+3 {
- // BMP images are stored in BGR order rather than RGB order.
- p[i+0] = b[j+2]
- p[i+1] = b[j+1]
- p[i+2] = b[j+0]
- p[i+3] = 0xFF
- }
- }
- return rgba, nil
-}
-
-// decodeNRGBA reads a 32 bit-per-pixel BMP image from r.
-// If topDown is false, the image rows will be read bottom-up.
-func decodeNRGBA(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
- rgba := image.NewNRGBA(image.Rect(0, 0, c.Width, c.Height))
- if c.Width == 0 || c.Height == 0 {
- return rgba, nil
- }
- y0, y1, yDelta := c.Height-1, -1, -1
- if topDown {
- y0, y1, yDelta = 0, c.Height, +1
- }
- for y := y0; y != y1; y += yDelta {
- p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
- if _, err := io.ReadFull(r, p); err != nil {
- return nil, err
- }
- for i := 0; i < len(p); i += 4 {
- // BMP images are stored in BGRA order rather than RGBA order.
- p[i+0], p[i+2] = p[i+2], p[i+0]
- }
- }
- return rgba, nil
-}
-
-// Decode reads a BMP image from r and returns it as an image.Image.
-// Limitation: The file must be 8, 24 or 32 bits per pixel.
-func Decode(r io.Reader) (image.Image, error) {
- c, bpp, topDown, err := decodeConfig(r)
- if err != nil {
- return nil, err
- }
- switch bpp {
- case 8:
- return decodePaletted(r, c, topDown)
- case 24:
- return decodeRGB(r, c, topDown)
- case 32:
- return decodeNRGBA(r, c, topDown)
- }
- panic("unreachable")
-}
-
-// DecodeConfig returns the color model and dimensions of a BMP image without
-// decoding the entire image.
-// Limitation: The file must be 8, 24 or 32 bits per pixel.
-func DecodeConfig(r io.Reader) (image.Config, error) {
- config, _, _, err := decodeConfig(r)
- return config, err
-}
-
-func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown bool, err error) {
- // We only support those BMP images that are a BITMAPFILEHEADER
- // immediately followed by a BITMAPINFOHEADER.
- const (
- fileHeaderLen = 14
- infoHeaderLen = 40
- )
- var b [1024]byte
- if _, err := io.ReadFull(r, b[:fileHeaderLen+infoHeaderLen]); err != nil {
- return image.Config{}, 0, false, err
- }
- if string(b[:2]) != "BM" {
- return image.Config{}, 0, false, errors.New("bmp: invalid format")
- }
- offset := readUint32(b[10:14])
- if readUint32(b[14:18]) != infoHeaderLen {
- return image.Config{}, 0, false, ErrUnsupported
- }
- width := int(int32(readUint32(b[18:22])))
- height := int(int32(readUint32(b[22:26])))
- if height < 0 {
- height, topDown = -height, true
- }
- if width < 0 || height < 0 {
- return image.Config{}, 0, false, ErrUnsupported
- }
- // We only support 1 plane, 8 or 24 bits per pixel and no compression.
- planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34])
- if planes != 1 || compression != 0 {
- return image.Config{}, 0, false, ErrUnsupported
- }
- switch bpp {
- case 8:
- if offset != fileHeaderLen+infoHeaderLen+256*4 {
- return image.Config{}, 0, false, ErrUnsupported
- }
- _, err = io.ReadFull(r, b[:256*4])
- if err != nil {
- return image.Config{}, 0, false, err
- }
- pcm := make(color.Palette, 256)
- for i := range pcm {
- // BMP images are stored in BGR order rather than RGB order.
- // Every 4th byte is padding.
- pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF}
- }
- return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, nil
- case 24:
- if offset != fileHeaderLen+infoHeaderLen {
- return image.Config{}, 0, false, ErrUnsupported
- }
- return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, nil
- case 32:
- if offset != fileHeaderLen+infoHeaderLen {
- return image.Config{}, 0, false, ErrUnsupported
- }
- return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, nil
- }
- return image.Config{}, 0, false, ErrUnsupported
-}
-
-func init() {
- image.RegisterFormat("bmp", "BM????\x00\x00\x00\x00", Decode, DecodeConfig)
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/bmp/writer.go b/Godeps/_workspace/src/golang.org/x/image/bmp/writer.go
deleted file mode 100644
index 6947968a4..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/bmp/writer.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bmp
-
-import (
- "encoding/binary"
- "errors"
- "image"
- "io"
-)
-
-type header struct {
- sigBM [2]byte
- fileSize uint32
- resverved [2]uint16
- pixOffset uint32
- dibHeaderSize uint32
- width uint32
- height uint32
- colorPlane uint16
- bpp uint16
- compression uint32
- imageSize uint32
- xPixelsPerMeter uint32
- yPixelsPerMeter uint32
- colorUse uint32
- colorImportant uint32
-}
-
-func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
- var padding []byte
- if dx < step {
- padding = make([]byte, step-dx)
- }
- for y := dy - 1; y >= 0; y-- {
- min := y*stride + 0
- max := y*stride + dx
- if _, err := w.Write(pix[min:max]); err != nil {
- return err
- }
- if padding != nil {
- if _, err := w.Write(padding); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
- buf := make([]byte, step)
- for y := dy - 1; y >= 0; y-- {
- min := y*stride + 0
- max := y*stride + dx*4
- off := 0
- for i := min; i < max; i += 4 {
- buf[off+2] = pix[i+0]
- buf[off+1] = pix[i+1]
- buf[off+0] = pix[i+2]
- off += 3
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-func encode(w io.Writer, m image.Image, step int) error {
- b := m.Bounds()
- buf := make([]byte, step)
- for y := b.Max.Y - 1; y >= b.Min.Y; y-- {
- off := 0
- for x := b.Min.X; x < b.Max.X; x++ {
- r, g, b, _ := m.At(x, y).RGBA()
- buf[off+2] = byte(r >> 8)
- buf[off+1] = byte(g >> 8)
- buf[off+0] = byte(b >> 8)
- off += 3
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-// Encode writes the image m to w in BMP format.
-func Encode(w io.Writer, m image.Image) error {
- d := m.Bounds().Size()
- if d.X < 0 || d.Y < 0 {
- return errors.New("bmp: negative bounds")
- }
- h := &header{
- sigBM: [2]byte{'B', 'M'},
- fileSize: 14 + 40,
- pixOffset: 14 + 40,
- dibHeaderSize: 40,
- width: uint32(d.X),
- height: uint32(d.Y),
- colorPlane: 1,
- }
-
- var step int
- var palette []byte
- switch m := m.(type) {
- case *image.Gray:
- step = (d.X + 3) &^ 3
- palette = make([]byte, 1024)
- for i := 0; i < 256; i++ {
- palette[i*4+0] = uint8(i)
- palette[i*4+1] = uint8(i)
- palette[i*4+2] = uint8(i)
- palette[i*4+3] = 0xFF
- }
- h.imageSize = uint32(d.Y * step)
- h.fileSize += uint32(len(palette)) + h.imageSize
- h.pixOffset += uint32(len(palette))
- h.bpp = 8
-
- case *image.Paletted:
- step = (d.X + 3) &^ 3
- palette = make([]byte, 1024)
- for i := 0; i < len(m.Palette) && i < 256; i++ {
- r, g, b, _ := m.Palette[i].RGBA()
- palette[i*4+0] = uint8(b >> 8)
- palette[i*4+1] = uint8(g >> 8)
- palette[i*4+2] = uint8(r >> 8)
- palette[i*4+3] = 0xFF
- }
- h.imageSize = uint32(d.Y * step)
- h.fileSize += uint32(len(palette)) + h.imageSize
- h.pixOffset += uint32(len(palette))
- h.bpp = 8
- default:
- step = (3*d.X + 3) &^ 3
- h.imageSize = uint32(d.Y * step)
- h.fileSize += h.imageSize
- h.bpp = 24
- }
-
- if err := binary.Write(w, binary.LittleEndian, h); err != nil {
- return err
- }
- if palette != nil {
- if err := binary.Write(w, binary.LittleEndian, palette); err != nil {
- return err
- }
- }
-
- if d.X == 0 || d.Y == 0 {
- return nil
- }
-
- switch m := m.(type) {
- case *image.Gray:
- return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
- case *image.Paletted:
- return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
- case *image.RGBA:
- return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step)
- }
- return encode(w, m, step)
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/basicfont.go b/Godeps/_workspace/src/golang.org/x/image/font/basicfont/basicfont.go
deleted file mode 100644
index 7eae19c8b..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/basicfont.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:generate go run gen.go
-
-// Package basicfont provides fixed-size font faces.
-package basicfont
-
-import (
- "image"
-
- "golang.org/x/image/math/fixed"
-)
-
-// Range maps a contiguous range of runes to vertically adjacent sub-images of
-// a Face's Mask image. The rune range is inclusive on the low end and
-// exclusive on the high end.
-//
-// If Low <= r && r < High, then the rune r is mapped to the sub-image of
-// Face.Mask whose bounds are image.Rect(0, y, Face.Width, y+Face.Height),
-// where y equals (int(r-Low) + Offset) * Face.Height.
-type Range struct {
- Low, High rune
- Offset int
-}
-
-// Face7x13 is a Face derived from the public domain X11 misc-fixed font files.
-//
-// At the moment, it holds the printable characters in ASCII starting with
-// space, and the Unicode replacement character U+FFFD.
-//
-// Its data is entirely self-contained and does not require loading from
-// separate files.
-var Face7x13 = &Face{
- Advance: 7,
- Width: 6,
- Height: 13,
- Ascent: 11,
- Mask: mask7x13,
- Ranges: []Range{
- {'\u0020', '\u007f', 0},
- {'\ufffd', '\ufffe', 95},
- },
-}
-
-// Face is a basic font face whose glyphs all have the same metrics.
-//
-// It is safe to use concurrently.
-type Face struct {
- // Advance is the glyph advance, in pixels.
- Advance int
- // Width is the glyph width, in pixels.
- Width int
- // Height is the glyph height, in pixels.
- Height int
- // Ascent is the glyph ascent, in pixels.
- Ascent int
-
- // TODO: do we also need Top and Left fields?
-
- // Mask contains all of the glyph masks. Its width is typically the Face's
- // Width, and its height a multiple of the Face's Height.
- Mask image.Image
- // Ranges map runes to sub-images of Mask. The rune ranges must not
- // overlap, and must be in increasing rune order.
- Ranges []Range
-}
-
-func (f *Face) Close() error { return nil }
-func (f *Face) Kern(r0, r1 rune) fixed.Int26_6 { return 0 }
-
-func (f *Face) Glyph(dot fixed.Point26_6, r rune) (
- dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
-
-loop:
- for _, rr := range [2]rune{r, '\ufffd'} {
- for _, rng := range f.Ranges {
- if rr < rng.Low || rng.High <= rr {
- continue
- }
- maskp.Y = (int(rr-rng.Low) + rng.Offset) * f.Height
- ok = true
- break loop
- }
- }
- if !ok {
- return image.Rectangle{}, nil, image.Point{}, 0, false
- }
-
- minX := int(dot.X+32) >> 6
- minY := int(dot.Y+32)>>6 - f.Ascent
- dr = image.Rectangle{
- Min: image.Point{
- X: minX,
- Y: minY,
- },
- Max: image.Point{
- X: minX + f.Width,
- Y: minY + f.Height,
- },
- }
-
- return dr, f.Mask, maskp, fixed.I(f.Advance), true
-}
-
-func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
- return fixed.R(0, -f.Ascent, f.Width, -f.Ascent+f.Height), fixed.I(f.Advance), true
-}
-
-func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
- return fixed.I(f.Advance), true
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/data.go b/Godeps/_workspace/src/golang.org/x/image/font/basicfont/data.go
deleted file mode 100644
index 883532117..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/data.go
+++ /dev/null
@@ -1,1456 +0,0 @@
-// generated by go generate; DO NOT EDIT.
-
-package basicfont
-
-// This data is derived from files in the font/fixed directory of the Plan 9
-// Port source code (https://github.com/9fans/plan9port) which were originally
-// based on the public domain X11 misc-fixed font files.
-
-import "image"
-
-// mask7x13 contains 96 6×13 glyphs in 7488 Pix bytes.
-var mask7x13 = &image.Alpha{
- Stride: 6,
- Rect: image.Rectangle{Max: image.Point{6, 96 * 13}},
- Pix: []byte{
- // 0x20 ' '
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x21 '!'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x22 '"'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x23 '#'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x24 '$'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x25 '%'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x26 '&'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x27 '\''
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x28 '('
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x29 ')'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2a '*'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2b '+'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2c ','
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2d '-'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2e '.'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x2f '/'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x30 '0'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x31 '1'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x32 '2'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x33 '3'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x34 '4'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x35 '5'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x36 '6'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x37 '7'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x38 '8'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x39 '9'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3a ':'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3b ';'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3c '<'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3d '='
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3e '>'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x3f '?'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x40 '@'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x41 'A'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x42 'B'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x43 'C'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x44 'D'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x45 'E'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x46 'F'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x47 'G'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x48 'H'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x49 'I'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4a 'J'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4b 'K'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4c 'L'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4d 'M'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4e 'N'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x4f 'O'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x50 'P'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x51 'Q'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x52 'R'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x53 'S'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x54 'T'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x55 'U'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x56 'V'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x57 'W'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x58 'X'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x59 'Y'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5a 'Z'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5b '['
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5c '\\'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5d ']'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5e '^'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x5f '_'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x60 '`'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x61 'a'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x62 'b'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x63 'c'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x64 'd'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x65 'e'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x66 'f'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x67 'g'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
-
- // 0x68 'h'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x69 'i'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x6a 'j'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
-
- // 0x6b 'k'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x6c 'l'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x6d 'm'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x6e 'n'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x6f 'o'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x70 'p'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x71 'q'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-
- // 0x72 'r'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x73 's'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x74 't'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x75 'u'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x76 'v'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x77 'w'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x78 'x'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x79 'y'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
-
- // 0x7a 'z'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x7b '{'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x7c '|'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x7d '}'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // 0x7e '~'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // U+FFFD REPLACEMENT CHARACTER
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0xff,
- 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/gen.go b/Godeps/_workspace/src/golang.org/x/image/font/basicfont/gen.go
deleted file mode 100644
index 67a21a74a..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/font/basicfont/gen.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// This program generates data.go.
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "image"
- "image/draw"
- "io/ioutil"
- "log"
- "path"
- "path/filepath"
-
- "golang.org/x/image/font"
- "golang.org/x/image/font/plan9font"
- "golang.org/x/image/math/fixed"
-)
-
-func main() {
- // nGlyphs is the number of glyphs to generate: 95 characters in the range
- // [0x20, 0x7e], plus the replacement character.
- const nGlyphs = 95 + 1
- // The particular font (unicode.7x13.font) leaves the right-most column
- // empty in its ASCII glyphs. We don't have to include that column in the
- // generated glyphs, so we subtract one off the effective width.
- const width, height, ascent = 7 - 1, 13, 11
-
- readFile := func(name string) ([]byte, error) {
- return ioutil.ReadFile(filepath.FromSlash(path.Join("../testdata/fixed", name)))
- }
- fontData, err := readFile("unicode.7x13.font")
- if err != nil {
- log.Fatalf("readFile: %v", err)
- }
- face, err := plan9font.ParseFont(fontData, readFile)
- if err != nil {
- log.Fatalf("plan9font.ParseFont: %v", err)
- }
-
- dst := image.NewRGBA(image.Rect(0, 0, width, nGlyphs*height))
- draw.Draw(dst, dst.Bounds(), image.Black, image.Point{}, draw.Src)
- d := &font.Drawer{
- Dst: dst,
- Src: image.White,
- Face: face,
- }
- for i := 0; i < nGlyphs; i++ {
- r := '\ufffd'
- if i < nGlyphs-1 {
- r = 0x20 + rune(i)
- }
- d.Dot = fixed.P(0, height*i+ascent)
- d.DrawString(string(r))
- }
-
- w := bytes.NewBuffer(nil)
- w.WriteString(preamble)
- fmt.Fprintf(w, "// mask7x13 contains %d %d×%d glyphs in %d Pix bytes.\n", nGlyphs, width, height, nGlyphs*width*height)
- fmt.Fprintf(w, "var mask7x13 = &image.Alpha{\n")
- fmt.Fprintf(w, " Stride: %d,\n", width)
- fmt.Fprintf(w, " Rect: image.Rectangle{Max: image.Point{%d, %d*%d}},\n", width, nGlyphs, height)
- fmt.Fprintf(w, " Pix: []byte{\n")
- b := dst.Bounds()
- for y := b.Min.Y; y < b.Max.Y; y++ {
- if y%height == 0 {
- if y != 0 {
- w.WriteByte('\n')
- }
- i := y / height
- if i < nGlyphs-1 {
- i += 0x20
- fmt.Fprintf(w, "// %#2x %q\n", i, rune(i))
- } else {
- fmt.Fprintf(w, "// U+FFFD REPLACEMENT CHARACTER\n")
- }
- }
-
- for x := b.Min.X; x < b.Max.X; x++ {
- if dst.RGBAAt(x, y).R > 0 {
- w.WriteString("0xff,")
- } else {
- w.WriteString("0x00,")
- }
- }
- w.WriteByte('\n')
- }
- w.WriteString("},\n}\n")
-
- fmted, err := format.Source(w.Bytes())
- if err != nil {
- log.Fatalf("format.Source: %v", err)
- }
- if err := ioutil.WriteFile("data.go", fmted, 0644); err != nil {
- log.Fatalf("ioutil.WriteFile: %v", err)
- }
-}
-
-const preamble = `// generated by go generate; DO NOT EDIT.
-
-package basicfont
-
-// This data is derived from files in the font/fixed directory of the Plan 9
-// Port source code (https://github.com/9fans/plan9port) which were originally
-// based on the public domain X11 misc-fixed font files.
-
-import "image"
-
-`
diff --git a/Godeps/_workspace/src/golang.org/x/image/font/font.go b/Godeps/_workspace/src/golang.org/x/image/font/font.go
deleted file mode 100644
index de8802fcc..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/font/font.go
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package font defines an interface for font faces, for drawing text on an
-// image.
-//
-// Other packages provide font face implementations. For example, a truetype
-// package would provide one based on .ttf font files.
-package font
-
-import (
- "image"
- "image/draw"
- "io"
-
- "golang.org/x/image/math/fixed"
-)
-
-// TODO: who is responsible for caches (glyph images, glyph indices, kerns)?
-// The Drawer or the Face?
-
-// Face is a font face. Its glyphs are often derived from a font file, such as
-// "Comic_Sans_MS.ttf", but a face has a specific size, style, weight and
-// hinting. For example, the 12pt and 18pt versions of Comic Sans are two
-// different faces, even if derived from the same font file.
-//
-// A Face is not safe for concurrent use by multiple goroutines, as its methods
-// may re-use implementation-specific caches and mask image buffers.
-//
-// To create a Face, look to other packages that implement specific font file
-// formats.
-type Face interface {
- io.Closer
-
- // Glyph returns the draw.DrawMask parameters (dr, mask, maskp) to draw r's
- // glyph at the sub-pixel destination location dot, and that glyph's
- // advance width.
- //
- // It returns !ok if the face does not contain a glyph for r.
- //
- // The contents of the mask image returned by one Glyph call may change
- // after the next Glyph call. Callers that want to cache the mask must make
- // a copy.
- Glyph(dot fixed.Point26_6, r rune) (
- dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool)
-
- // GlyphBounds returns the bounding box of r's glyph, drawn at a dot equal
- // to the origin, and that glyph's advance width.
- //
- // It returns !ok if the face does not contain a glyph for r.
- //
- // The glyph's ascent and descent equal -bounds.Min.Y and +bounds.Max.Y. A
- // visual depiction of what these metrics are is at
- // https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png
- GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool)
-
- // GlyphAdvance returns the advance width of r's glyph.
- //
- // It returns !ok if the face does not contain a glyph for r.
- GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool)
-
- // Kern returns the horizontal adjustment for the kerning pair (r0, r1). A
- // positive kern means to move the glyphs further apart.
- Kern(r0, r1 rune) fixed.Int26_6
-
- // TODO: per-font Metrics.
- // TODO: ColoredGlyph for various emoji?
- // TODO: Ligatures? Shaping?
-}
-
-// TODO: Drawer.Layout or Drawer.Measure methods to measure text without
-// drawing?
-
-// Drawer draws text on a destination image.
-//
-// A Drawer is not safe for concurrent use by multiple goroutines, since its
-// Face is not.
-type Drawer struct {
- // Dst is the destination image.
- Dst draw.Image
- // Src is the source image.
- Src image.Image
- // Face provides the glyph mask images.
- Face Face
- // Dot is the baseline location to draw the next glyph. The majority of the
- // affected pixels will be above and to the right of the dot, but some may
- // be below or to the left. For example, drawing a 'j' in an italic face
- // may affect pixels below and to the left of the dot.
- Dot fixed.Point26_6
-
- // TODO: Clip image.Image?
- // TODO: SrcP image.Point for Src images other than *image.Uniform? How
- // does it get updated during DrawString?
-}
-
-// TODO: should DrawString return the last rune drawn, so the next DrawString
-// call can kern beforehand? Or should that be the responsibility of the caller
-// if they really want to do that, since they have to explicitly shift d.Dot
-// anyway?
-//
-// In general, we'd have a DrawBytes([]byte) and DrawRuneReader(io.RuneReader)
-// and the last case can't assume that you can rewind the stream.
-//
-// TODO: how does this work with line breaking: drawing text up until a
-// vertical line? Should DrawString return the number of runes drawn?
-
-// DrawString draws s at the dot and advances the dot's location.
-func (d *Drawer) DrawString(s string) {
- var prevC rune
- for i, c := range s {
- if i != 0 {
- d.Dot.X += d.Face.Kern(prevC, c)
- }
- dr, mask, maskp, advance, ok := d.Face.Glyph(d.Dot, c)
- if !ok {
- // TODO: is falling back on the U+FFFD glyph the responsibility of
- // the Drawer or the Face?
- // TODO: set prevC = '\ufffd'?
- continue
- }
- draw.DrawMask(d.Dst, dr, d.Src, image.Point{}, mask, maskp, draw.Over)
- d.Dot.X += advance
- prevC = c
- }
-}
-
-// MeasureString returns how far dot would advance by drawing s.
-func (d *Drawer) MeasureString(s string) (advance fixed.Int26_6) {
- var prevC rune
- for i, c := range s {
- if i != 0 {
- advance += d.Face.Kern(prevC, c)
- }
- a, ok := d.Face.GlyphAdvance(c)
- if !ok {
- // TODO: is falling back on the U+FFFD glyph the responsibility of
- // the Drawer or the Face?
- // TODO: set prevC = '\ufffd'?
- continue
- }
- advance += a
- prevC = c
- }
- return advance
-}
-
-// Hinting selects how to quantize a vector font's glyph nodes.
-//
-// Not all fonts support hinting.
-type Hinting int
-
-const (
- HintingNone Hinting = iota
- HintingVertical
- HintingFull
-)
-
-// Stretch selects a normal, condensed, or expanded face.
-//
-// Not all fonts support stretches.
-type Stretch int
-
-const (
- StretchUltraCondensed Stretch = -4
- StretchExtraCondensed Stretch = -3
- StretchCondensed Stretch = -2
- StretchSemiCondensed Stretch = -1
- StretchNormal Stretch = +0
- StretchSemiExpanded Stretch = +1
- StretchExpanded Stretch = +2
- StretchExtraExpanded Stretch = +3
- StretchUltraExpanded Stretch = +4
-)
-
-// Style selects a normal, italic, or oblique face.
-//
-// Not all fonts support styles.
-type Style int
-
-const (
- StyleNormal Style = iota
- StyleItalic
- StyleOblique
-)
-
-// Weight selects a normal, light or bold face.
-//
-// Not all fonts support weights.
-type Weight int
-
-const (
- WeightThin Weight = 100
- WeightExtraLight Weight = 200
- WeightLight Weight = 300
- WeightNormal Weight = 400
- WeightMedium Weight = 500
- WeightSemiBold Weight = 600
- WeightBold Weight = 700
- WeightExtraBold Weight = 800
- WeightBlack Weight = 900
-)
diff --git a/Godeps/_workspace/src/golang.org/x/image/font/plan9font/plan9font.go b/Godeps/_workspace/src/golang.org/x/image/font/plan9font/plan9font.go
deleted file mode 100644
index 9c686b776..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/font/plan9font/plan9font.go
+++ /dev/null
@@ -1,556 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package plan9font implements font faces for the Plan 9 font and subfont file
-// formats. These formats are described at
-// http://plan9.bell-labs.com/magic/man2html/6/font
-package plan9font
-
-// TODO: have a subface use an *image.Alpha instead of plan9Image implementing
-// the image.Image interface? The image/draw code has a fast path for
-// *image.Alpha masks.
-
-import (
- "bytes"
- "errors"
- "fmt"
- "image"
- "image/color"
- "log"
- "strconv"
- "strings"
-
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-// fontchar describes one character glyph in a subfont.
-//
-// For more detail, look for "struct Fontchar" in
-// http://plan9.bell-labs.com/magic/man2html/2/cachechars
-type fontchar struct {
- x uint32 // X position in the image holding the glyphs.
- top uint8 // First non-zero scan line.
- bottom uint8 // Last non-zero scan line.
- left int8 // Offset of baseline.
- width uint8 // Width of baseline.
-}
-
-func parseFontchars(p []byte) []fontchar {
- fc := make([]fontchar, len(p)/6)
- for i := range fc {
- fc[i] = fontchar{
- x: uint32(p[0]) | uint32(p[1])<<8,
- top: uint8(p[2]),
- bottom: uint8(p[3]),
- left: int8(p[4]),
- width: uint8(p[5]),
- }
- p = p[6:]
- }
- return fc
-}
-
-// subface implements font.Face for a Plan 9 subfont.
-type subface struct {
- firstRune rune // First rune in the subfont.
- n int // Number of characters in the subfont.
- height int // Inter-line spacing.
- ascent int // Height above the baseline.
- fontchars []fontchar // Character descriptions.
- img *plan9Image // Image holding the glyphs.
-}
-
-func (f *subface) Close() error { return nil }
-func (f *subface) Kern(r0, r1 rune) fixed.Int26_6 { return 0 }
-
-func (f *subface) Glyph(dot fixed.Point26_6, r rune) (
- dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
-
- r -= f.firstRune
- if r < 0 || f.n <= int(r) {
- return image.Rectangle{}, nil, image.Point{}, 0, false
- }
- i := &f.fontchars[r+0]
- j := &f.fontchars[r+1]
-
- minX := int(dot.X+32)>>6 + int(i.left)
- minY := int(dot.Y+32)>>6 + int(i.top) - f.ascent
- dr = image.Rectangle{
- Min: image.Point{
- X: minX,
- Y: minY,
- },
- Max: image.Point{
- X: minX + int(j.x-i.x),
- Y: minY + int(i.bottom) - int(i.top),
- },
- }
- return dr, f.img, image.Point{int(i.x), int(i.top)}, fixed.Int26_6(i.width) << 6, true
-}
-
-func (f *subface) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
- r -= f.firstRune
- if r < 0 || f.n <= int(r) {
- return fixed.Rectangle26_6{}, 0, false
- }
- i := &f.fontchars[r+0]
- j := &f.fontchars[r+1]
-
- bounds = fixed.R(
- int(i.left),
- int(i.top)-f.ascent,
- int(i.left)+int(j.x-i.x),
- int(i.bottom)-f.ascent,
- )
- return bounds, fixed.Int26_6(i.width) << 6, true
-}
-
-func (f *subface) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
- r -= f.firstRune
- if r < 0 || f.n <= int(r) {
- return 0, false
- }
- return fixed.Int26_6(f.fontchars[r].width) << 6, true
-}
-
-// runeRange maps a single rune range [lo, hi] to a lazily loaded subface. Both
-// ends of the range are inclusive.
-type runeRange struct {
- lo, hi rune
- offset rune // subfont index that the lo rune maps to.
- relFilename string
- subface *subface
- bad bool
-}
-
-// face implements font.Face for a Plan 9 font.
-//
-// It maps multiple rune ranges to *subface values. Rune ranges may overlap;
-// the first match wins.
-type face struct {
- height int
- ascent int
- readFile func(relFilename string) ([]byte, error)
- runeRanges []runeRange
-}
-
-func (f *face) Close() error { return nil }
-func (f *face) Kern(r0, r1 rune) fixed.Int26_6 { return 0 }
-
-func (f *face) Glyph(dot fixed.Point26_6, r rune) (
- dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
-
- if s, rr := f.subface(r); s != nil {
- return s.Glyph(dot, rr)
- }
- return image.Rectangle{}, nil, image.Point{}, 0, false
-}
-
-func (f *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
- if s, rr := f.subface(r); s != nil {
- return s.GlyphBounds(rr)
- }
- return fixed.Rectangle26_6{}, 0, false
-}
-
-func (f *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
- if s, rr := f.subface(r); s != nil {
- return s.GlyphAdvance(rr)
- }
- return 0, false
-}
-
-func (f *face) subface(r rune) (*subface, rune) {
- // Fall back on U+FFFD if we can't find r.
- for _, rr := range [2]rune{r, '\ufffd'} {
- // We have to do linear, not binary search. plan9port's
- // lucsans/unicode.8.font says:
- // 0x2591 0x2593 ../luc/Altshades.7.0
- // 0x2500 0x25ee ../luc/FormBlock.7.0
- // and the rune ranges overlap.
- for i := range f.runeRanges {
- x := &f.runeRanges[i]
- if rr < x.lo || x.hi < rr || x.bad {
- continue
- }
- if x.subface == nil {
- data, err := f.readFile(x.relFilename)
- if err != nil {
- log.Printf("plan9font: couldn't read subfont %q: %v", x.relFilename, err)
- x.bad = true
- continue
- }
- sub, err := ParseSubfont(data, x.lo-x.offset)
- if err != nil {
- log.Printf("plan9font: couldn't parse subfont %q: %v", x.relFilename, err)
- x.bad = true
- continue
- }
- x.subface = sub.(*subface)
- }
- return x.subface, rr
- }
- }
- return nil, 0
-}
-
-// ParseFont parses a Plan 9 font file. data is the contents of that font file,
-// which gives relative filenames for subfont files. readFile returns the
-// contents of those subfont files. It is similar to io/ioutil's ReadFile
-// function, except that it takes a relative filename instead of an absolute
-// one.
-func ParseFont(data []byte, readFile func(relFilename string) ([]byte, error)) (font.Face, error) {
- f := &face{
- readFile: readFile,
- }
- // TODO: don't use strconv, to avoid the conversions from []byte to string?
- for first := true; len(data) > 0; first = false {
- i := bytes.IndexByte(data, '\n')
- if i < 0 {
- return nil, errors.New("plan9font: invalid font: no final newline")
- }
- row := string(data[:i])
- data = data[i+1:]
- if first {
- height, s, ok := nextInt32(row)
- if !ok {
- return nil, fmt.Errorf("plan9font: invalid font: invalid header %q", row)
- }
- ascent, s, ok := nextInt32(s)
- if !ok {
- return nil, fmt.Errorf("plan9font: invalid font: invalid header %q", row)
- }
- if height < 0 || 0xffff < height || ascent < 0 || 0xffff < ascent {
- return nil, fmt.Errorf("plan9font: invalid font: invalid header %q", row)
- }
- f.height, f.ascent = int(height), int(ascent)
- continue
- }
- lo, s, ok := nextInt32(row)
- if !ok {
- return nil, fmt.Errorf("plan9font: invalid font: invalid row %q", row)
- }
- hi, s, ok := nextInt32(s)
- if !ok {
- return nil, fmt.Errorf("plan9font: invalid font: invalid row %q", row)
- }
- offset, s, _ := nextInt32(s)
-
- f.runeRanges = append(f.runeRanges, runeRange{
- lo: lo,
- hi: hi,
- offset: offset,
- relFilename: s,
- })
- }
- return f, nil
-}
-
-func nextInt32(s string) (ret int32, remaining string, ok bool) {
- i := 0
- for ; i < len(s) && s[i] <= ' '; i++ {
- }
- j := i
- for ; j < len(s) && s[j] > ' '; j++ {
- }
- n, err := strconv.ParseInt(s[i:j], 0, 32)
- if err != nil {
- return 0, s, false
- }
- for ; j < len(s) && s[j] <= ' '; j++ {
- }
- return int32(n), s[j:], true
-}
-
-// ParseSubfont parses a Plan 9 subfont file.
-//
-// firstRune is the first rune in the subfont file. For example, the
-// Phonetic.6.0 subfont, containing glyphs in the range U+0250 to U+02E9, would
-// set firstRune to '\u0250'.
-func ParseSubfont(data []byte, firstRune rune) (font.Face, error) {
- data, m, err := parseImage(data)
- if err != nil {
- return nil, err
- }
- if len(data) < 3*12 {
- return nil, errors.New("plan9font: invalid subfont: header too short")
- }
- n := atoi(data[0*12:])
- height := atoi(data[1*12:])
- ascent := atoi(data[2*12:])
- data = data[3*12:]
- if len(data) != 6*(n+1) {
- return nil, errors.New("plan9font: invalid subfont: data length mismatch")
- }
- return &subface{
- firstRune: firstRune,
- n: n,
- height: height,
- ascent: ascent,
- fontchars: parseFontchars(data),
- img: m,
- }, nil
-}
-
-// plan9Image implements that subset of the Plan 9 image feature set that is
-// used by this font file format.
-//
-// Some features, such as the repl bit and a clip rectangle, are omitted for
-// simplicity.
-type plan9Image struct {
- depth int // Depth of the pixels in bits.
- width int // Width in bytes of a single scan line.
- rect image.Rectangle // Extent of the image.
- pix []byte // Pixel bits.
-}
-
-func (m *plan9Image) byteoffset(x, y int) int {
- a := y * m.width
- if m.depth < 8 {
- // We need to always round down, but Go rounds toward zero.
- np := 8 / m.depth
- if x < 0 {
- return a + (x-np+1)/np
- }
- return a + x/np
- }
- return a + x*(m.depth/8)
-}
-
-func (m *plan9Image) Bounds() image.Rectangle { return m.rect }
-func (m *plan9Image) ColorModel() color.Model { return color.AlphaModel }
-
-func (m *plan9Image) At(x, y int) color.Color {
- if (image.Point{x, y}).In(m.rect) {
- b := m.pix[m.byteoffset(x, y)]
- switch m.depth {
- case 1:
- // CGrey, 1.
- mask := uint8(1 << uint8(7-x&7))
- if (b & mask) != 0 {
- return color.Alpha{0xff}
- }
- return color.Alpha{0x00}
- case 2:
- // CGrey, 2.
- shift := uint(x&3) << 1
- // Place pixel at top of word.
- y := b << shift
- y &= 0xc0
- // Replicate throughout.
- y |= y >> 2
- y |= y >> 4
- return color.Alpha{y}
- }
- }
- return color.Alpha{0x00}
-}
-
-var compressed = []byte("compressed\n")
-
-func parseImage(data []byte) (remainingData []byte, m *plan9Image, retErr error) {
- if !bytes.HasPrefix(data, compressed) {
- return nil, nil, errors.New("plan9font: unsupported uncompressed format")
- }
- data = data[len(compressed):]
-
- const hdrSize = 5 * 12
- if len(data) < hdrSize {
- return nil, nil, errors.New("plan9font: invalid image: header too short")
- }
- hdr, data := data[:hdrSize], data[hdrSize:]
-
- // Distinguish new channel descriptor from old ldepth. Channel descriptors
- // have letters as well as numbers, while ldepths are a single digit
- // formatted as %-11d.
- new := false
- for m := 0; m < 10; m++ {
- if hdr[m] != ' ' {
- new = true
- break
- }
- }
- if hdr[11] != ' ' {
- return nil, nil, errors.New("plan9font: invalid image: bad header")
- }
- if !new {
- return nil, nil, errors.New("plan9font: unsupported ldepth format")
- }
-
- depth := 0
- switch s := strings.TrimSpace(string(hdr[:1*12])); s {
- default:
- return nil, nil, fmt.Errorf("plan9font: unsupported pixel format %q", s)
- case "k1":
- depth = 1
- case "k2":
- depth = 2
- }
- r := ator(hdr[1*12:])
- if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
- return nil, nil, errors.New("plan9font: invalid image: bad rectangle")
- }
-
- width := bytesPerLine(r, depth)
- m = &plan9Image{
- depth: depth,
- width: width,
- rect: r,
- pix: make([]byte, width*r.Dy()),
- }
-
- miny := r.Min.Y
- for miny != r.Max.Y {
- if len(data) < 2*12 {
- return nil, nil, errors.New("plan9font: invalid image: data band too short")
- }
- maxy := atoi(data[0*12:])
- nb := atoi(data[1*12:])
- data = data[2*12:]
-
- if len(data) < nb {
- return nil, nil, errors.New("plan9font: invalid image: data band length mismatch")
- }
- buf := data[:nb]
- data = data[nb:]
-
- if maxy <= miny || r.Max.Y < maxy {
- return nil, nil, fmt.Errorf("plan9font: bad maxy %d", maxy)
- }
- // An old-format image would flip the bits here, but we don't support
- // the old format.
- rr := r
- rr.Min.Y = miny
- rr.Max.Y = maxy
- if err := decompress(m, rr, buf); err != nil {
- return nil, nil, err
- }
- miny = maxy
- }
- return data, m, nil
-}
-
-// Compressed data are sequences of byte codes. If the first byte b has the
-// 0x80 bit set, the next (b^0x80)+1 bytes are data. Otherwise, these two bytes
-// specify a previous string to repeat.
-const (
- compShortestMatch = 3 // shortest match possible.
- compWindowSize = 1024 // window size.
-)
-
-var (
- errDecompressBufferTooSmall = errors.New("plan9font: decompress: buffer too small")
- errDecompressPhaseError = errors.New("plan9font: decompress: phase error")
-)
-
-func decompress(m *plan9Image, r image.Rectangle, data []byte) error {
- if !r.In(m.rect) {
- return errors.New("plan9font: decompress: bad rectangle")
- }
- bpl := bytesPerLine(r, m.depth)
- mem := make([]byte, compWindowSize)
- memi := 0
- omemi := -1
- y := r.Min.Y
- linei := m.byteoffset(r.Min.X, y)
- eline := linei + bpl
- datai := 0
- for {
- if linei == eline {
- y++
- if y == r.Max.Y {
- break
- }
- linei = m.byteoffset(r.Min.X, y)
- eline = linei + bpl
- }
- if datai == len(data) {
- return errDecompressBufferTooSmall
- }
- c := data[datai]
- datai++
- if c >= 128 {
- for cnt := c - 128 + 1; cnt != 0; cnt-- {
- if datai == len(data) {
- return errDecompressBufferTooSmall
- }
- if linei == eline {
- return errDecompressPhaseError
- }
- m.pix[linei] = data[datai]
- linei++
- mem[memi] = data[datai]
- memi++
- datai++
- if memi == len(mem) {
- memi = 0
- }
- }
- } else {
- if datai == len(data) {
- return errDecompressBufferTooSmall
- }
- offs := int(data[datai]) + ((int(c) & 3) << 8) + 1
- datai++
- if memi < offs {
- omemi = memi + (compWindowSize - offs)
- } else {
- omemi = memi - offs
- }
- for cnt := (c >> 2) + compShortestMatch; cnt != 0; cnt-- {
- if linei == eline {
- return errDecompressPhaseError
- }
- m.pix[linei] = mem[omemi]
- linei++
- mem[memi] = mem[omemi]
- memi++
- omemi++
- if omemi == len(mem) {
- omemi = 0
- }
- if memi == len(mem) {
- memi = 0
- }
- }
- }
- }
- return nil
-}
-
-func ator(b []byte) image.Rectangle {
- return image.Rectangle{atop(b), atop(b[2*12:])}
-}
-
-func atop(b []byte) image.Point {
- return image.Pt(atoi(b), atoi(b[12:]))
-}
-
-func atoi(b []byte) int {
- i := 0
- for ; i < len(b) && b[i] == ' '; i++ {
- }
- n := 0
- for ; i < len(b) && '0' <= b[i] && b[i] <= '9'; i++ {
- n = n*10 + int(b[i]) - '0'
- }
- return n
-}
-
-func bytesPerLine(r image.Rectangle, depth int) int {
- if depth <= 0 || 32 < depth {
- panic("invalid depth")
- }
- var l int
- if r.Min.X >= 0 {
- l = (r.Max.X*depth + 7) / 8
- l -= (r.Min.X * depth) / 8
- } else {
- // Make positive before divide.
- t := (-r.Min.X*depth + 7) / 8
- l = t + (r.Max.X*depth+7)/8
- }
- return l
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/math/fixed/fixed.go b/Godeps/_workspace/src/golang.org/x/image/math/fixed/fixed.go
deleted file mode 100644
index 7af56d9ee..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/math/fixed/fixed.go
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package fixed implements fixed-point integer types.
-package fixed
-
-import (
- "fmt"
-)
-
-// TODO: implement fmt.Formatter for %f and %g.
-
-// I returns the integer value i as an Int26_6.
-//
-// For example, passing the integer value 2 yields Int26_6(128).
-func I(i int) Int26_6 {
- return Int26_6(i << 6)
-}
-
-// Int26_6 is a signed 26.6 fixed-point number.
-//
-// The integer part ranges from -33554432 to 33554431, inclusive. The
-// fractional part has 6 bits of precision.
-//
-// For example, the number one-and-a-quarter is Int26_6(1<<6 + 1<<4).
-type Int26_6 int32
-
-// String returns a human-readable representation of a 26.6 fixed-point number.
-//
-// For example, the number one-and-a-quarter becomes "1:16".
-func (x Int26_6) String() string {
- const shift, mask = 6, 1<<6 - 1
- if x >= 0 {
- return fmt.Sprintf("%d:%02d", int32(x>>shift), int32(x&mask))
- }
- x = -x
- if x >= 0 {
- return fmt.Sprintf("-%d:%02d", int32(x>>shift), int32(x&mask))
- }
- return "-33554432:00" // The minimum value is -(1<<25).
-}
-
-// Int52_12 is a signed 52.12 fixed-point number.
-//
-// The integer part ranges from -2251799813685248 to 2251799813685247,
-// inclusive. The fractional part has 12 bits of precision.
-//
-// For example, the number one-and-a-quarter is Int52_12(1<<12 + 1<<10).
-type Int52_12 int64
-
-// String returns a human-readable representation of a 52.12 fixed-point
-// number.
-//
-// For example, the number one-and-a-quarter becomes "1:1024".
-func (x Int52_12) String() string {
- const shift, mask = 12, 1<<12 - 1
- if x >= 0 {
- return fmt.Sprintf("%d:%04d", int64(x>>shift), int64(x&mask))
- }
- x = -x
- if x >= 0 {
- return fmt.Sprintf("-%d:%04d", int64(x>>shift), int64(x&mask))
- }
- return "-2251799813685248:0000" // The minimum value is -(1<<51).
-}
-
-// P returns the integer values x and y as a Point26_6.
-//
-// For example, passing the integer values (2, -3) yields Point26_6{128, -192}.
-func P(x, y int) Point26_6 {
- return Point26_6{Int26_6(x << 6), Int26_6(y << 6)}
-}
-
-// Point26_6 is a 26.6 fixed-point coordinate pair.
-//
-// It is analogous to the image.Point type in the standard library.
-type Point26_6 struct {
- X, Y Int26_6
-}
-
-// Add returns the vector p+q.
-func (p Point26_6) Add(q Point26_6) Point26_6 {
- return Point26_6{p.X + q.X, p.Y + q.Y}
-}
-
-// Sub returns the vector p-q.
-func (p Point26_6) Sub(q Point26_6) Point26_6 {
- return Point26_6{p.X - q.X, p.Y - q.Y}
-}
-
-// Mul returns the vector p*k.
-func (p Point26_6) Mul(k Int26_6) Point26_6 {
- return Point26_6{p.X * k / 64, p.Y * k / 64}
-}
-
-// Div returns the vector p/k.
-func (p Point26_6) Div(k Int26_6) Point26_6 {
- return Point26_6{p.X * 64 / k, p.Y * 64 / k}
-}
-
-// Point52_12 is a 52.12 fixed-point coordinate pair.
-//
-// It is analogous to the image.Point type in the standard library.
-type Point52_12 struct {
- X, Y Int52_12
-}
-
-// Add returns the vector p+q.
-func (p Point52_12) Add(q Point52_12) Point52_12 {
- return Point52_12{p.X + q.X, p.Y + q.Y}
-}
-
-// Sub returns the vector p-q.
-func (p Point52_12) Sub(q Point52_12) Point52_12 {
- return Point52_12{p.X - q.X, p.Y - q.Y}
-}
-
-// Mul returns the vector p*k.
-func (p Point52_12) Mul(k Int52_12) Point52_12 {
- return Point52_12{p.X * k / 4096, p.Y * k / 4096}
-}
-
-// Div returns the vector p/k.
-func (p Point52_12) Div(k Int52_12) Point52_12 {
- return Point52_12{p.X * 4096 / k, p.Y * 4096 / k}
-}
-
-// R returns the integer values minX, minY, maxX, maxY as a Rectangle26_6.
-//
-// For example, passing the integer values (0, 1, 2, 3) yields
-// Rectangle26_6{Point26_6{0, 64}, Point26_6{128, 192}}.
-//
-// Like the image.Rect function in the standard library, the returned rectangle
-// has minimum and maximum coordinates swapped if necessary so that it is
-// well-formed.
-func R(minX, minY, maxX, maxY int) Rectangle26_6 {
- if minX > maxX {
- minX, maxX = maxX, minX
- }
- if minY > maxY {
- minY, maxY = maxY, minY
- }
- return Rectangle26_6{
- Point26_6{
- Int26_6(minX << 6),
- Int26_6(minY << 6),
- },
- Point26_6{
- Int26_6(maxX << 6),
- Int26_6(maxY << 6),
- },
- }
-}
-
-// Rectangle26_6 is a 26.6 fixed-point coordinate rectangle. The Min bound is
-// inclusive and the Max bound is exclusive. It is well-formed if Min.X <=
-// Max.X and likewise for Y.
-//
-// It is analogous to the image.Rectangle type in the standard library.
-type Rectangle26_6 struct {
- Min, Max Point26_6
-}
-
-// Rectangle52_12 is a 52.12 fixed-point coordinate rectangle. The Min bound is
-// inclusive and the Max bound is exclusive. It is well-formed if Min.X <=
-// Max.X and likewise for Y.
-//
-// It is analogous to the image.Rectangle type in the standard library.
-type Rectangle52_12 struct {
- Min, Max Point52_12
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/buffer.go b/Godeps/_workspace/src/golang.org/x/image/tiff/buffer.go
deleted file mode 100644
index d1801be48..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/buffer.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tiff
-
-import "io"
-
-// buffer buffers an io.Reader to satisfy io.ReaderAt.
-type buffer struct {
- r io.Reader
- buf []byte
-}
-
-// fill reads data from b.r until the buffer contains at least end bytes.
-func (b *buffer) fill(end int) error {
- m := len(b.buf)
- if end > m {
- if end > cap(b.buf) {
- newcap := 1024
- for newcap < end {
- newcap *= 2
- }
- newbuf := make([]byte, end, newcap)
- copy(newbuf, b.buf)
- b.buf = newbuf
- } else {
- b.buf = b.buf[:end]
- }
- if n, err := io.ReadFull(b.r, b.buf[m:end]); err != nil {
- end = m + n
- b.buf = b.buf[:end]
- return err
- }
- }
- return nil
-}
-
-func (b *buffer) ReadAt(p []byte, off int64) (int, error) {
- o := int(off)
- end := o + len(p)
- if int64(end) != off+int64(len(p)) {
- return 0, io.ErrUnexpectedEOF
- }
-
- err := b.fill(end)
- return copy(p, b.buf[o:end]), err
-}
-
-// Slice returns a slice of the underlying buffer. The slice contains
-// n bytes starting at offset off.
-func (b *buffer) Slice(off, n int) ([]byte, error) {
- end := off + n
- if err := b.fill(end); err != nil {
- return nil, err
- }
- return b.buf[off:end], nil
-}
-
-// newReaderAt converts an io.Reader into an io.ReaderAt.
-func newReaderAt(r io.Reader) io.ReaderAt {
- if ra, ok := r.(io.ReaderAt); ok {
- return ra
- }
- return &buffer{
- r: r,
- buf: make([]byte, 0, 1024),
- }
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/compress.go b/Godeps/_workspace/src/golang.org/x/image/tiff/compress.go
deleted file mode 100644
index 3f176f00a..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/compress.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tiff
-
-import (
- "bufio"
- "io"
-)
-
-type byteReader interface {
- io.Reader
- io.ByteReader
-}
-
-// unpackBits decodes the PackBits-compressed data in src and returns the
-// uncompressed data.
-//
-// The PackBits compression format is described in section 9 (p. 42)
-// of the TIFF spec.
-func unpackBits(r io.Reader) ([]byte, error) {
- buf := make([]byte, 128)
- dst := make([]byte, 0, 1024)
- br, ok := r.(byteReader)
- if !ok {
- br = bufio.NewReader(r)
- }
-
- for {
- b, err := br.ReadByte()
- if err != nil {
- if err == io.EOF {
- return dst, nil
- }
- return nil, err
- }
- code := int(int8(b))
- switch {
- case code >= 0:
- n, err := io.ReadFull(br, buf[:code+1])
- if err != nil {
- return nil, err
- }
- dst = append(dst, buf[:n]...)
- case code == -128:
- // No-op.
- default:
- if b, err = br.ReadByte(); err != nil {
- return nil, err
- }
- for j := 0; j < 1-code; j++ {
- buf[j] = b
- }
- dst = append(dst, buf[:1-code]...)
- }
- }
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/consts.go b/Godeps/_workspace/src/golang.org/x/image/tiff/consts.go
deleted file mode 100644
index 3c51a70be..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/consts.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tiff
-
-// A tiff image file contains one or more images. The metadata
-// of each image is contained in an Image File Directory (IFD),
-// which contains entries of 12 bytes each and is described
-// on page 14-16 of the specification. An IFD entry consists of
-//
-// - a tag, which describes the signification of the entry,
-// - the data type and length of the entry,
-// - the data itself or a pointer to it if it is more than 4 bytes.
-//
-// The presence of a length means that each IFD is effectively an array.
-
-const (
- leHeader = "II\x2A\x00" // Header for little-endian files.
- beHeader = "MM\x00\x2A" // Header for big-endian files.
-
- ifdLen = 12 // Length of an IFD entry in bytes.
-)
-
-// Data types (p. 14-16 of the spec).
-const (
- dtByte = 1
- dtASCII = 2
- dtShort = 3
- dtLong = 4
- dtRational = 5
-)
-
-// The length of one instance of each data type in bytes.
-var lengths = [...]uint32{0, 1, 1, 2, 4, 8}
-
-// Tags (see p. 28-41 of the spec).
-const (
- tImageWidth = 256
- tImageLength = 257
- tBitsPerSample = 258
- tCompression = 259
- tPhotometricInterpretation = 262
-
- tStripOffsets = 273
- tSamplesPerPixel = 277
- tRowsPerStrip = 278
- tStripByteCounts = 279
-
- tTileWidth = 322
- tTileLength = 323
- tTileOffsets = 324
- tTileByteCounts = 325
-
- tXResolution = 282
- tYResolution = 283
- tResolutionUnit = 296
-
- tPredictor = 317
- tColorMap = 320
- tExtraSamples = 338
- tSampleFormat = 339
-)
-
-// Compression types (defined in various places in the spec and supplements).
-const (
- cNone = 1
- cCCITT = 2
- cG3 = 3 // Group 3 Fax.
- cG4 = 4 // Group 4 Fax.
- cLZW = 5
- cJPEGOld = 6 // Superseded by cJPEG.
- cJPEG = 7
- cDeflate = 8 // zlib compression.
- cPackBits = 32773
- cDeflateOld = 32946 // Superseded by cDeflate.
-)
-
-// Photometric interpretation values (see p. 37 of the spec).
-const (
- pWhiteIsZero = 0
- pBlackIsZero = 1
- pRGB = 2
- pPaletted = 3
- pTransMask = 4 // transparency mask
- pCMYK = 5
- pYCbCr = 6
- pCIELab = 8
-)
-
-// Values for the tPredictor tag (page 64-65 of the spec).
-const (
- prNone = 1
- prHorizontal = 2
-)
-
-// Values for the tResolutionUnit tag (page 18).
-const (
- resNone = 1
- resPerInch = 2 // Dots per inch.
- resPerCM = 3 // Dots per centimeter.
-)
-
-// imageMode represents the mode of the image.
-type imageMode int
-
-const (
- mBilevel imageMode = iota
- mPaletted
- mGray
- mGrayInvert
- mRGB
- mRGBA
- mNRGBA
-)
-
-// CompressionType describes the type of compression used in Options.
-type CompressionType int
-
-const (
- Uncompressed CompressionType = iota
- Deflate
-)
-
-// specValue returns the compression type constant from the TIFF spec that
-// is equivalent to c.
-func (c CompressionType) specValue() uint32 {
- switch c {
- case Deflate:
- return cDeflate
- }
- return cNone
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/lzw/reader.go b/Godeps/_workspace/src/golang.org/x/image/tiff/lzw/reader.go
deleted file mode 100644
index dc9f7dd1d..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/lzw/reader.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package lzw implements the Lempel-Ziv-Welch compressed data format,
-// described in T. A. Welch, ``A Technique for High-Performance Data
-// Compression'', Computer, 17(6) (June 1984), pp 8-19.
-//
-// In particular, it implements LZW as used by the TIFF file format, including
-// an "off by one" algorithmic difference when compared to standard LZW.
-package lzw
-
-/*
-This file was branched from src/pkg/compress/lzw/reader.go in the
-standard library. Differences from the original are marked with "NOTE".
-
-The tif_lzw.c file in the libtiff C library has this comment:
-
-----
-The 5.0 spec describes a different algorithm than Aldus
-implements. Specifically, Aldus does code length transitions
-one code earlier than should be done (for real LZW).
-Earlier versions of this library implemented the correct
-LZW algorithm, but emitted codes in a bit order opposite
-to the TIFF spec. Thus, to maintain compatibility w/ Aldus
-we interpret MSB-LSB ordered codes to be images written w/
-old versions of this library, but otherwise adhere to the
-Aldus "off by one" algorithm.
-----
-
-The Go code doesn't read (invalid) TIFF files written by old versions of
-libtiff, but the LZW algorithm in this package still differs from the one in
-Go's standard package library to accomodate this "off by one" in valid TIFFs.
-*/
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
-)
-
-// Order specifies the bit ordering in an LZW data stream.
-type Order int
-
-const (
- // LSB means Least Significant Bits first, as used in the GIF file format.
- LSB Order = iota
- // MSB means Most Significant Bits first, as used in the TIFF and PDF
- // file formats.
- MSB
-)
-
-const (
- maxWidth = 12
- decoderInvalidCode = 0xffff
- flushBuffer = 1 << maxWidth
-)
-
-// decoder is the state from which the readXxx method converts a byte
-// stream into a code stream.
-type decoder struct {
- r io.ByteReader
- bits uint32
- nBits uint
- width uint
- read func(*decoder) (uint16, error) // readLSB or readMSB
- litWidth int // width in bits of literal codes
- err error
-
- // The first 1<<litWidth codes are literal codes.
- // The next two codes mean clear and EOF.
- // Other valid codes are in the range [lo, hi] where lo := clear + 2,
- // with the upper bound incrementing on each code seen.
- // overflow is the code at which hi overflows the code width. NOTE: TIFF's LZW is "off by one".
- // last is the most recently seen code, or decoderInvalidCode.
- clear, eof, hi, overflow, last uint16
-
- // Each code c in [lo, hi] expands to two or more bytes. For c != hi:
- // suffix[c] is the last of these bytes.
- // prefix[c] is the code for all but the last byte.
- // This code can either be a literal code or another code in [lo, c).
- // The c == hi case is a special case.
- suffix [1 << maxWidth]uint8
- prefix [1 << maxWidth]uint16
-
- // output is the temporary output buffer.
- // Literal codes are accumulated from the start of the buffer.
- // Non-literal codes decode to a sequence of suffixes that are first
- // written right-to-left from the end of the buffer before being copied
- // to the start of the buffer.
- // It is flushed when it contains >= 1<<maxWidth bytes,
- // so that there is always room to decode an entire code.
- output [2 * 1 << maxWidth]byte
- o int // write index into output
- toRead []byte // bytes to return from Read
-}
-
-// readLSB returns the next code for "Least Significant Bits first" data.
-func (d *decoder) readLSB() (uint16, error) {
- for d.nBits < d.width {
- x, err := d.r.ReadByte()
- if err != nil {
- return 0, err
- }
- d.bits |= uint32(x) << d.nBits
- d.nBits += 8
- }
- code := uint16(d.bits & (1<<d.width - 1))
- d.bits >>= d.width
- d.nBits -= d.width
- return code, nil
-}
-
-// readMSB returns the next code for "Most Significant Bits first" data.
-func (d *decoder) readMSB() (uint16, error) {
- for d.nBits < d.width {
- x, err := d.r.ReadByte()
- if err != nil {
- return 0, err
- }
- d.bits |= uint32(x) << (24 - d.nBits)
- d.nBits += 8
- }
- code := uint16(d.bits >> (32 - d.width))
- d.bits <<= d.width
- d.nBits -= d.width
- return code, nil
-}
-
-func (d *decoder) Read(b []byte) (int, error) {
- for {
- if len(d.toRead) > 0 {
- n := copy(b, d.toRead)
- d.toRead = d.toRead[n:]
- return n, nil
- }
- if d.err != nil {
- return 0, d.err
- }
- d.decode()
- }
-}
-
-// decode decompresses bytes from r and leaves them in d.toRead.
-// read specifies how to decode bytes into codes.
-// litWidth is the width in bits of literal codes.
-func (d *decoder) decode() {
- // Loop over the code stream, converting codes into decompressed bytes.
- for {
- code, err := d.read(d)
- if err != nil {
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- d.err = err
- d.flush()
- return
- }
- switch {
- case code < d.clear:
- // We have a literal code.
- d.output[d.o] = uint8(code)
- d.o++
- if d.last != decoderInvalidCode {
- // Save what the hi code expands to.
- d.suffix[d.hi] = uint8(code)
- d.prefix[d.hi] = d.last
- }
- case code == d.clear:
- d.width = 1 + uint(d.litWidth)
- d.hi = d.eof
- d.overflow = 1 << d.width
- d.last = decoderInvalidCode
- continue
- case code == d.eof:
- d.flush()
- d.err = io.EOF
- return
- case code <= d.hi:
- c, i := code, len(d.output)-1
- if code == d.hi {
- // code == hi is a special case which expands to the last expansion
- // followed by the head of the last expansion. To find the head, we walk
- // the prefix chain until we find a literal code.
- c = d.last
- for c >= d.clear {
- c = d.prefix[c]
- }
- d.output[i] = uint8(c)
- i--
- c = d.last
- }
- // Copy the suffix chain into output and then write that to w.
- for c >= d.clear {
- d.output[i] = d.suffix[c]
- i--
- c = d.prefix[c]
- }
- d.output[i] = uint8(c)
- d.o += copy(d.output[d.o:], d.output[i:])
- if d.last != decoderInvalidCode {
- // Save what the hi code expands to.
- d.suffix[d.hi] = uint8(c)
- d.prefix[d.hi] = d.last
- }
- default:
- d.err = errors.New("lzw: invalid code")
- d.flush()
- return
- }
- d.last, d.hi = code, d.hi+1
- if d.hi+1 >= d.overflow { // NOTE: the "+1" is where TIFF's LZW differs from the standard algorithm.
- if d.width == maxWidth {
- d.last = decoderInvalidCode
- } else {
- d.width++
- d.overflow <<= 1
- }
- }
- if d.o >= flushBuffer {
- d.flush()
- return
- }
- }
-}
-
-func (d *decoder) flush() {
- d.toRead = d.output[:d.o]
- d.o = 0
-}
-
-var errClosed = errors.New("lzw: reader/writer is closed")
-
-func (d *decoder) Close() error {
- d.err = errClosed // in case any Reads come along
- return nil
-}
-
-// NewReader creates a new io.ReadCloser.
-// Reads from the returned io.ReadCloser read and decompress data from r.
-// If r does not also implement io.ByteReader,
-// the decompressor may read more data than necessary from r.
-// It is the caller's responsibility to call Close on the ReadCloser when
-// finished reading.
-// The number of bits to use for literal codes, litWidth, must be in the
-// range [2,8] and is typically 8. It must equal the litWidth
-// used during compression.
-func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
- d := new(decoder)
- switch order {
- case LSB:
- d.read = (*decoder).readLSB
- case MSB:
- d.read = (*decoder).readMSB
- default:
- d.err = errors.New("lzw: unknown order")
- return d
- }
- if litWidth < 2 || 8 < litWidth {
- d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
- return d
- }
- if br, ok := r.(io.ByteReader); ok {
- d.r = br
- } else {
- d.r = bufio.NewReader(r)
- }
- d.litWidth = litWidth
- d.width = 1 + uint(litWidth)
- d.clear = uint16(1) << uint(litWidth)
- d.eof, d.hi = d.clear+1, d.clear+1
- d.overflow = uint16(1) << d.width
- d.last = decoderInvalidCode
-
- return d
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/reader.go b/Godeps/_workspace/src/golang.org/x/image/tiff/reader.go
deleted file mode 100644
index 714e3dda7..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/reader.go
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package tiff implements a TIFF image decoder and encoder.
-//
-// The TIFF specification is at http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
-package tiff
-
-import (
- "compress/zlib"
- "encoding/binary"
- "fmt"
- "image"
- "image/color"
- "io"
- "io/ioutil"
- "math"
-
- "golang.org/x/image/tiff/lzw"
-)
-
-// A FormatError reports that the input is not a valid TIFF image.
-type FormatError string
-
-func (e FormatError) Error() string {
- return "tiff: invalid format: " + string(e)
-}
-
-// An UnsupportedError reports that the input uses a valid but
-// unimplemented feature.
-type UnsupportedError string
-
-func (e UnsupportedError) Error() string {
- return "tiff: unsupported feature: " + string(e)
-}
-
-// An InternalError reports that an internal error was encountered.
-type InternalError string
-
-func (e InternalError) Error() string {
- return "tiff: internal error: " + string(e)
-}
-
-var errNoPixels = FormatError("not enough pixel data")
-
-type decoder struct {
- r io.ReaderAt
- byteOrder binary.ByteOrder
- config image.Config
- mode imageMode
- bpp uint
- features map[int][]uint
- palette []color.Color
-
- buf []byte
- off int // Current offset in buf.
- v uint32 // Buffer value for reading with arbitrary bit depths.
- nbits uint // Remaining number of bits in v.
-}
-
-// firstVal returns the first uint of the features entry with the given tag,
-// or 0 if the tag does not exist.
-func (d *decoder) firstVal(tag int) uint {
- f := d.features[tag]
- if len(f) == 0 {
- return 0
- }
- return f[0]
-}
-
-// ifdUint decodes the IFD entry in p, which must be of the Byte, Short
-// or Long type, and returns the decoded uint values.
-func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
- var raw []byte
- if len(p) < ifdLen {
- return nil, FormatError("bad IFD entry")
- }
-
- datatype := d.byteOrder.Uint16(p[2:4])
- if dt := int(datatype); dt <= 0 || dt >= len(lengths) {
- return nil, UnsupportedError("IFD entry datatype")
- }
-
- count := d.byteOrder.Uint32(p[4:8])
- if count > math.MaxInt32/lengths[datatype] {
- return nil, FormatError("IFD data too large")
- }
- if datalen := lengths[datatype] * count; datalen > 4 {
- // The IFD contains a pointer to the real value.
- raw = make([]byte, datalen)
- _, err = d.r.ReadAt(raw, int64(d.byteOrder.Uint32(p[8:12])))
- } else {
- raw = p[8 : 8+datalen]
- }
- if err != nil {
- return nil, err
- }
-
- u = make([]uint, count)
- switch datatype {
- case dtByte:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(raw[i])
- }
- case dtShort:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(d.byteOrder.Uint16(raw[2*i : 2*(i+1)]))
- }
- case dtLong:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(d.byteOrder.Uint32(raw[4*i : 4*(i+1)]))
- }
- default:
- return nil, UnsupportedError("data type")
- }
- return u, nil
-}
-
-// parseIFD decides whether the the IFD entry in p is "interesting" and
-// stows away the data in the decoder.
-func (d *decoder) parseIFD(p []byte) error {
- tag := d.byteOrder.Uint16(p[0:2])
- switch tag {
- case tBitsPerSample,
- tExtraSamples,
- tPhotometricInterpretation,
- tCompression,
- tPredictor,
- tStripOffsets,
- tStripByteCounts,
- tRowsPerStrip,
- tTileWidth,
- tTileLength,
- tTileOffsets,
- tTileByteCounts,
- tImageLength,
- tImageWidth:
- val, err := d.ifdUint(p)
- if err != nil {
- return err
- }
- d.features[int(tag)] = val
- case tColorMap:
- val, err := d.ifdUint(p)
- if err != nil {
- return err
- }
- numcolors := len(val) / 3
- if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
- return FormatError("bad ColorMap length")
- }
- d.palette = make([]color.Color, numcolors)
- for i := 0; i < numcolors; i++ {
- d.palette[i] = color.RGBA64{
- uint16(val[i]),
- uint16(val[i+numcolors]),
- uint16(val[i+2*numcolors]),
- 0xffff,
- }
- }
- case tSampleFormat:
- // Page 27 of the spec: If the SampleFormat is present and
- // the value is not 1 [= unsigned integer data], a Baseline
- // TIFF reader that cannot handle the SampleFormat value
- // must terminate the import process gracefully.
- val, err := d.ifdUint(p)
- if err != nil {
- return err
- }
- for _, v := range val {
- if v != 1 {
- return UnsupportedError("sample format")
- }
- }
- }
- return nil
-}
-
-// readBits reads n bits from the internal buffer starting at the current offset.
-func (d *decoder) readBits(n uint) (v uint32, ok bool) {
- for d.nbits < n {
- d.v <<= 8
- if d.off >= len(d.buf) {
- return 0, false
- }
- d.v |= uint32(d.buf[d.off])
- d.off++
- d.nbits += 8
- }
- d.nbits -= n
- rv := d.v >> d.nbits
- d.v &^= rv << d.nbits
- return rv, true
-}
-
-// flushBits discards the unread bits in the buffer used by readBits.
-// It is used at the end of a line.
-func (d *decoder) flushBits() {
- d.v = 0
- d.nbits = 0
-}
-
-// minInt returns the smaller of x or y.
-func minInt(a, b int) int {
- if a <= b {
- return a
- }
- return b
-}
-
-// decode decodes the raw data of an image.
-// It reads from d.buf and writes the strip or tile into dst.
-func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error {
- d.off = 0
-
- // Apply horizontal predictor if necessary.
- // In this case, p contains the color difference to the preceding pixel.
- // See page 64-65 of the spec.
- if d.firstVal(tPredictor) == prHorizontal {
- switch d.bpp {
- case 16:
- var off int
- n := 2 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel
- for y := ymin; y < ymax; y++ {
- off += n
- for x := 0; x < (xmax-xmin-1)*n; x += 2 {
- if off+2 > len(d.buf) {
- return errNoPixels
- }
- v0 := d.byteOrder.Uint16(d.buf[off-n : off-n+2])
- v1 := d.byteOrder.Uint16(d.buf[off : off+2])
- d.byteOrder.PutUint16(d.buf[off:off+2], v1+v0)
- off += 2
- }
- }
- case 8:
- var off int
- n := 1 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel
- for y := ymin; y < ymax; y++ {
- off += n
- for x := 0; x < (xmax-xmin-1)*n; x++ {
- if off >= len(d.buf) {
- return errNoPixels
- }
- d.buf[off] += d.buf[off-n]
- off++
- }
- }
- case 1:
- return UnsupportedError("horizontal predictor with 1 BitsPerSample")
- }
- }
-
- rMaxX := minInt(xmax, dst.Bounds().Max.X)
- rMaxY := minInt(ymax, dst.Bounds().Max.Y)
- switch d.mode {
- case mGray, mGrayInvert:
- if d.bpp == 16 {
- img := dst.(*image.Gray16)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+2 > len(d.buf) {
- return errNoPixels
- }
- v := d.byteOrder.Uint16(d.buf[d.off : d.off+2])
- d.off += 2
- if d.mode == mGrayInvert {
- v = 0xffff - v
- }
- img.SetGray16(x, y, color.Gray16{v})
- }
- }
- } else {
- img := dst.(*image.Gray)
- max := uint32((1 << d.bpp) - 1)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- v, ok := d.readBits(d.bpp)
- if !ok {
- return errNoPixels
- }
- v = v * 0xff / max
- if d.mode == mGrayInvert {
- v = 0xff - v
- }
- img.SetGray(x, y, color.Gray{uint8(v)})
- }
- d.flushBits()
- }
- }
- case mPaletted:
- img := dst.(*image.Paletted)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- v, ok := d.readBits(d.bpp)
- if !ok {
- return errNoPixels
- }
- img.SetColorIndex(x, y, uint8(v))
- }
- d.flushBits()
- }
- case mRGB:
- if d.bpp == 16 {
- img := dst.(*image.RGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+6 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- d.off += 6
- img.SetRGBA64(x, y, color.RGBA64{r, g, b, 0xffff})
- }
- }
- } else {
- img := dst.(*image.RGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- off := (y - ymin) * (xmax - xmin) * 3
- for i := min; i < max; i += 4 {
- if off+3 > len(d.buf) {
- return errNoPixels
- }
- img.Pix[i+0] = d.buf[off+0]
- img.Pix[i+1] = d.buf[off+1]
- img.Pix[i+2] = d.buf[off+2]
- img.Pix[i+3] = 0xff
- off += 3
- }
- }
- }
- case mNRGBA:
- if d.bpp == 16 {
- img := dst.(*image.NRGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+8 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8])
- d.off += 8
- img.SetNRGBA64(x, y, color.NRGBA64{r, g, b, a})
- }
- }
- } else {
- img := dst.(*image.NRGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4
- if i1 > len(d.buf) {
- return errNoPixels
- }
- copy(img.Pix[min:max], d.buf[i0:i1])
- }
- }
- case mRGBA:
- if d.bpp == 16 {
- img := dst.(*image.RGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+8 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8])
- d.off += 8
- img.SetRGBA64(x, y, color.RGBA64{r, g, b, a})
- }
- }
- } else {
- img := dst.(*image.RGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4
- if i1 > len(d.buf) {
- return errNoPixels
- }
- copy(img.Pix[min:max], d.buf[i0:i1])
- }
- }
- }
-
- return nil
-}
-
-func newDecoder(r io.Reader) (*decoder, error) {
- d := &decoder{
- r: newReaderAt(r),
- features: make(map[int][]uint),
- }
-
- p := make([]byte, 8)
- if _, err := d.r.ReadAt(p, 0); err != nil {
- return nil, err
- }
- switch string(p[0:4]) {
- case leHeader:
- d.byteOrder = binary.LittleEndian
- case beHeader:
- d.byteOrder = binary.BigEndian
- default:
- return nil, FormatError("malformed header")
- }
-
- ifdOffset := int64(d.byteOrder.Uint32(p[4:8]))
-
- // The first two bytes contain the number of entries (12 bytes each).
- if _, err := d.r.ReadAt(p[0:2], ifdOffset); err != nil {
- return nil, err
- }
- numItems := int(d.byteOrder.Uint16(p[0:2]))
-
- // All IFD entries are read in one chunk.
- p = make([]byte, ifdLen*numItems)
- if _, err := d.r.ReadAt(p, ifdOffset+2); err != nil {
- return nil, err
- }
-
- for i := 0; i < len(p); i += ifdLen {
- if err := d.parseIFD(p[i : i+ifdLen]); err != nil {
- return nil, err
- }
- }
-
- d.config.Width = int(d.firstVal(tImageWidth))
- d.config.Height = int(d.firstVal(tImageLength))
-
- if _, ok := d.features[tBitsPerSample]; !ok {
- return nil, FormatError("BitsPerSample tag missing")
- }
- d.bpp = d.firstVal(tBitsPerSample)
- switch d.bpp {
- case 0:
- return nil, FormatError("BitsPerSample must not be 0")
- case 1, 8, 16:
- // Nothing to do, these are accepted by this implementation.
- default:
- return nil, UnsupportedError(fmt.Sprintf("BitsPerSample of %v", d.bpp))
- }
-
- // Determine the image mode.
- switch d.firstVal(tPhotometricInterpretation) {
- case pRGB:
- if d.bpp == 16 {
- for _, b := range d.features[tBitsPerSample] {
- if b != 16 {
- return nil, FormatError("wrong number of samples for 16bit RGB")
- }
- }
- } else {
- for _, b := range d.features[tBitsPerSample] {
- if b != 8 {
- return nil, FormatError("wrong number of samples for 8bit RGB")
- }
- }
- }
- // RGB images normally have 3 samples per pixel.
- // If there are more, ExtraSamples (p. 31-32 of the spec)
- // gives their meaning (usually an alpha channel).
- //
- // This implementation does not support extra samples
- // of an unspecified type.
- switch len(d.features[tBitsPerSample]) {
- case 3:
- d.mode = mRGB
- if d.bpp == 16 {
- d.config.ColorModel = color.RGBA64Model
- } else {
- d.config.ColorModel = color.RGBAModel
- }
- case 4:
- switch d.firstVal(tExtraSamples) {
- case 1:
- d.mode = mRGBA
- if d.bpp == 16 {
- d.config.ColorModel = color.RGBA64Model
- } else {
- d.config.ColorModel = color.RGBAModel
- }
- case 2:
- d.mode = mNRGBA
- if d.bpp == 16 {
- d.config.ColorModel = color.NRGBA64Model
- } else {
- d.config.ColorModel = color.NRGBAModel
- }
- default:
- return nil, FormatError("wrong number of samples for RGB")
- }
- default:
- return nil, FormatError("wrong number of samples for RGB")
- }
- case pPaletted:
- d.mode = mPaletted
- d.config.ColorModel = color.Palette(d.palette)
- case pWhiteIsZero:
- d.mode = mGrayInvert
- if d.bpp == 16 {
- d.config.ColorModel = color.Gray16Model
- } else {
- d.config.ColorModel = color.GrayModel
- }
- case pBlackIsZero:
- d.mode = mGray
- if d.bpp == 16 {
- d.config.ColorModel = color.Gray16Model
- } else {
- d.config.ColorModel = color.GrayModel
- }
- default:
- return nil, UnsupportedError("color model")
- }
-
- return d, nil
-}
-
-// DecodeConfig returns the color model and dimensions of a TIFF image without
-// decoding the entire image.
-func DecodeConfig(r io.Reader) (image.Config, error) {
- d, err := newDecoder(r)
- if err != nil {
- return image.Config{}, err
- }
- return d.config, nil
-}
-
-// Decode reads a TIFF image from r and returns it as an image.Image.
-// The type of Image returned depends on the contents of the TIFF.
-func Decode(r io.Reader) (img image.Image, err error) {
- d, err := newDecoder(r)
- if err != nil {
- return
- }
-
- blockPadding := false
- blockWidth := d.config.Width
- blockHeight := d.config.Height
- blocksAcross := 1
- blocksDown := 1
-
- if d.config.Width == 0 {
- blocksAcross = 0
- }
- if d.config.Height == 0 {
- blocksDown = 0
- }
-
- var blockOffsets, blockCounts []uint
-
- if int(d.firstVal(tTileWidth)) != 0 {
- blockPadding = true
-
- blockWidth = int(d.firstVal(tTileWidth))
- blockHeight = int(d.firstVal(tTileLength))
-
- if blockWidth != 0 {
- blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth
- }
- if blockHeight != 0 {
- blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
- }
-
- blockCounts = d.features[tTileByteCounts]
- blockOffsets = d.features[tTileOffsets]
-
- } else {
- if int(d.firstVal(tRowsPerStrip)) != 0 {
- blockHeight = int(d.firstVal(tRowsPerStrip))
- }
-
- if blockHeight != 0 {
- blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
- }
-
- blockOffsets = d.features[tStripOffsets]
- blockCounts = d.features[tStripByteCounts]
- }
-
- // Check if we have the right number of strips/tiles, offsets and counts.
- if n := blocksAcross * blocksDown; len(blockOffsets) < n || len(blockCounts) < n {
- return nil, FormatError("inconsistent header")
- }
-
- imgRect := image.Rect(0, 0, d.config.Width, d.config.Height)
- switch d.mode {
- case mGray, mGrayInvert:
- if d.bpp == 16 {
- img = image.NewGray16(imgRect)
- } else {
- img = image.NewGray(imgRect)
- }
- case mPaletted:
- img = image.NewPaletted(imgRect, d.palette)
- case mNRGBA:
- if d.bpp == 16 {
- img = image.NewNRGBA64(imgRect)
- } else {
- img = image.NewNRGBA(imgRect)
- }
- case mRGB, mRGBA:
- if d.bpp == 16 {
- img = image.NewRGBA64(imgRect)
- } else {
- img = image.NewRGBA(imgRect)
- }
- }
-
- for i := 0; i < blocksAcross; i++ {
- blkW := blockWidth
- if !blockPadding && i == blocksAcross-1 && d.config.Width%blockWidth != 0 {
- blkW = d.config.Width % blockWidth
- }
- for j := 0; j < blocksDown; j++ {
- blkH := blockHeight
- if !blockPadding && j == blocksDown-1 && d.config.Height%blockHeight != 0 {
- blkH = d.config.Height % blockHeight
- }
- offset := int64(blockOffsets[j*blocksAcross+i])
- n := int64(blockCounts[j*blocksAcross+i])
- switch d.firstVal(tCompression) {
-
- // According to the spec, Compression does not have a default value,
- // but some tools interpret a missing Compression value as none so we do
- // the same.
- case cNone, 0:
- if b, ok := d.r.(*buffer); ok {
- d.buf, err = b.Slice(int(offset), int(n))
- } else {
- d.buf = make([]byte, n)
- _, err = d.r.ReadAt(d.buf, offset)
- }
- case cLZW:
- r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8)
- d.buf, err = ioutil.ReadAll(r)
- r.Close()
- case cDeflate, cDeflateOld:
- var r io.ReadCloser
- r, err = zlib.NewReader(io.NewSectionReader(d.r, offset, n))
- if err != nil {
- return nil, err
- }
- d.buf, err = ioutil.ReadAll(r)
- r.Close()
- case cPackBits:
- d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
- default:
- err = UnsupportedError(fmt.Sprintf("compression value %d", d.firstVal(tCompression)))
- }
- if err != nil {
- return nil, err
- }
-
- xmin := i * blockWidth
- ymin := j * blockHeight
- xmax := xmin + blkW
- ymax := ymin + blkH
- err = d.decode(img, xmin, ymin, xmax, ymax)
- if err != nil {
- return nil, err
- }
- }
- }
- return
-}
-
-func init() {
- image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig)
- image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig)
-}
diff --git a/Godeps/_workspace/src/golang.org/x/image/tiff/writer.go b/Godeps/_workspace/src/golang.org/x/image/tiff/writer.go
deleted file mode 100644
index c8a01cea7..000000000
--- a/Godeps/_workspace/src/golang.org/x/image/tiff/writer.go
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tiff
-
-import (
- "bytes"
- "compress/zlib"
- "encoding/binary"
- "image"
- "io"
- "sort"
-)
-
-// The TIFF format allows to choose the order of the different elements freely.
-// The basic structure of a TIFF file written by this package is:
-//
-// 1. Header (8 bytes).
-// 2. Image data.
-// 3. Image File Directory (IFD).
-// 4. "Pointer area" for larger entries in the IFD.
-
-// We only write little-endian TIFF files.
-var enc = binary.LittleEndian
-
-// An ifdEntry is a single entry in an Image File Directory.
-// A value of type dtRational is composed of two 32-bit values,
-// thus data contains two uints (numerator and denominator) for a single number.
-type ifdEntry struct {
- tag int
- datatype int
- data []uint32
-}
-
-func (e ifdEntry) putData(p []byte) {
- for _, d := range e.data {
- switch e.datatype {
- case dtByte, dtASCII:
- p[0] = byte(d)
- p = p[1:]
- case dtShort:
- enc.PutUint16(p, uint16(d))
- p = p[2:]
- case dtLong, dtRational:
- enc.PutUint32(p, uint32(d))
- p = p[4:]
- }
- }
-}
-
-type byTag []ifdEntry
-
-func (d byTag) Len() int { return len(d) }
-func (d byTag) Less(i, j int) bool { return d[i].tag < d[j].tag }
-func (d byTag) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
-
-func encodeGray(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error {
- if !predictor {
- return writePix(w, pix, dy, dx, stride)
- }
- buf := make([]byte, dx)
- for y := 0; y < dy; y++ {
- min := y*stride + 0
- max := y*stride + dx
- off := 0
- var v0 uint8
- for i := min; i < max; i++ {
- v1 := pix[i]
- buf[off] = v1 - v0
- v0 = v1
- off++
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-func encodeGray16(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error {
- buf := make([]byte, dx*2)
- for y := 0; y < dy; y++ {
- min := y*stride + 0
- max := y*stride + dx*2
- off := 0
- var v0 uint16
- for i := min; i < max; i += 2 {
- // An image.Gray16's Pix is in big-endian order.
- v1 := uint16(pix[i])<<8 | uint16(pix[i+1])
- if predictor {
- v0, v1 = v1, v1-v0
- }
- // We only write little-endian TIFF files.
- buf[off+0] = byte(v1)
- buf[off+1] = byte(v1 >> 8)
- off += 2
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error {
- if !predictor {
- return writePix(w, pix, dy, dx*4, stride)
- }
- buf := make([]byte, dx*4)
- for y := 0; y < dy; y++ {
- min := y*stride + 0
- max := y*stride + dx*4
- off := 0
- var r0, g0, b0, a0 uint8
- for i := min; i < max; i += 4 {
- r1, g1, b1, a1 := pix[i+0], pix[i+1], pix[i+2], pix[i+3]
- buf[off+0] = r1 - r0
- buf[off+1] = g1 - g0
- buf[off+2] = b1 - b0
- buf[off+3] = a1 - a0
- off += 4
- r0, g0, b0, a0 = r1, g1, b1, a1
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-func encodeRGBA64(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error {
- buf := make([]byte, dx*8)
- for y := 0; y < dy; y++ {
- min := y*stride + 0
- max := y*stride + dx*8
- off := 0
- var r0, g0, b0, a0 uint16
- for i := min; i < max; i += 8 {
- // An image.RGBA64's Pix is in big-endian order.
- r1 := uint16(pix[i+0])<<8 | uint16(pix[i+1])
- g1 := uint16(pix[i+2])<<8 | uint16(pix[i+3])
- b1 := uint16(pix[i+4])<<8 | uint16(pix[i+5])
- a1 := uint16(pix[i+6])<<8 | uint16(pix[i+7])
- if predictor {
- r0, r1 = r1, r1-r0
- g0, g1 = g1, g1-g0
- b0, b1 = b1, b1-b0
- a0, a1 = a1, a1-a0
- }
- // We only write little-endian TIFF files.
- buf[off+0] = byte(r1)
- buf[off+1] = byte(r1 >> 8)
- buf[off+2] = byte(g1)
- buf[off+3] = byte(g1 >> 8)
- buf[off+4] = byte(b1)
- buf[off+5] = byte(b1 >> 8)
- buf[off+6] = byte(a1)
- buf[off+7] = byte(a1 >> 8)
- off += 8
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-func encode(w io.Writer, m image.Image, predictor bool) error {
- bounds := m.Bounds()
- buf := make([]byte, 4*bounds.Dx())
- for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
- off := 0
- if predictor {
- var r0, g0, b0, a0 uint8
- for x := bounds.Min.X; x < bounds.Max.X; x++ {
- r, g, b, a := m.At(x, y).RGBA()
- r1 := uint8(r >> 8)
- g1 := uint8(g >> 8)
- b1 := uint8(b >> 8)
- a1 := uint8(a >> 8)
- buf[off+0] = r1 - r0
- buf[off+1] = g1 - g0
- buf[off+2] = b1 - b0
- buf[off+3] = a1 - a0
- off += 4
- r0, g0, b0, a0 = r1, g1, b1, a1
- }
- } else {
- for x := bounds.Min.X; x < bounds.Max.X; x++ {
- r, g, b, a := m.At(x, y).RGBA()
- buf[off+0] = uint8(r >> 8)
- buf[off+1] = uint8(g >> 8)
- buf[off+2] = uint8(b >> 8)
- buf[off+3] = uint8(a >> 8)
- off += 4
- }
- }
- if _, err := w.Write(buf); err != nil {
- return err
- }
- }
- return nil
-}
-
-// writePix writes the internal byte array of an image to w. It is less general
-// but much faster then encode. writePix is used when pix directly
-// corresponds to one of the TIFF image types.
-func writePix(w io.Writer, pix []byte, nrows, length, stride int) error {
- if length == stride {
- _, err := w.Write(pix[:nrows*length])
- return err
- }
- for ; nrows > 0; nrows-- {
- if _, err := w.Write(pix[:length]); err != nil {
- return err
- }
- pix = pix[stride:]
- }
- return nil
-}
-
-func writeIFD(w io.Writer, ifdOffset int, d []ifdEntry) error {
- var buf [ifdLen]byte
- // Make space for "pointer area" containing IFD entry data
- // longer than 4 bytes.
- parea := make([]byte, 1024)
- pstart := ifdOffset + ifdLen*len(d) + 6
- var o int // Current offset in parea.
-
- // The IFD has to be written with the tags in ascending order.
- sort.Sort(byTag(d))
-
- // Write the number of entries in this IFD.
- if err := binary.Write(w, enc, uint16(len(d))); err != nil {
- return err
- }
- for _, ent := range d {
- enc.PutUint16(buf[0:2], uint16(ent.tag))
- enc.PutUint16(buf[2:4], uint16(ent.datatype))
- count := uint32(len(ent.data))
- if ent.datatype == dtRational {
- count /= 2
- }
- enc.PutUint32(buf[4:8], count)
- datalen := int(count * lengths[ent.datatype])
- if datalen <= 4 {
- ent.putData(buf[8:12])
- } else {
- if (o + datalen) > len(parea) {
- newlen := len(parea) + 1024
- for (o + datalen) > newlen {
- newlen += 1024
- }
- newarea := make([]byte, newlen)
- copy(newarea, parea)
- parea = newarea
- }
- ent.putData(parea[o : o+datalen])
- enc.PutUint32(buf[8:12], uint32(pstart+o))
- o += datalen
- }
- if _, err := w.Write(buf[:]); err != nil {
- return err
- }
- }
- // The IFD ends with the offset of the next IFD in the file,
- // or zero if it is the last one (page 14).
- if err := binary.Write(w, enc, uint32(0)); err != nil {
- return err
- }
- _, err := w.Write(parea[:o])
- return err
-}
-
-// Options are the encoding parameters.
-type Options struct {
- // Compression is the type of compression used.
- Compression CompressionType
- // Predictor determines whether a differencing predictor is used;
- // if true, instead of each pixel's color, the color difference to the
- // preceding one is saved. This improves the compression for certain
- // types of images and compressors. For example, it works well for
- // photos with Deflate compression.
- Predictor bool
-}
-
-// Encode writes the image m to w. opt determines the options used for
-// encoding, such as the compression type. If opt is nil, an uncompressed
-// image is written.
-func Encode(w io.Writer, m image.Image, opt *Options) error {
- d := m.Bounds().Size()
-
- compression := uint32(cNone)
- predictor := false
- if opt != nil {
- compression = opt.Compression.specValue()
- // The predictor field is only used with LZW. See page 64 of the spec.
- predictor = opt.Predictor && compression == cLZW
- }
-
- _, err := io.WriteString(w, leHeader)
- if err != nil {
- return err
- }
-
- // Compressed data is written into a buffer first, so that we
- // know the compressed size.
- var buf bytes.Buffer
- // dst holds the destination for the pixel data of the image --
- // either w or a writer to buf.
- var dst io.Writer
- // imageLen is the length of the pixel data in bytes.
- // The offset of the IFD is imageLen + 8 header bytes.
- var imageLen int
-
- switch compression {
- case cNone:
- dst = w
- // Write IFD offset before outputting pixel data.
- switch m.(type) {
- case *image.Paletted:
- imageLen = d.X * d.Y * 1
- case *image.Gray:
- imageLen = d.X * d.Y * 1
- case *image.Gray16:
- imageLen = d.X * d.Y * 2
- case *image.RGBA64:
- imageLen = d.X * d.Y * 8
- case *image.NRGBA64:
- imageLen = d.X * d.Y * 8
- default:
- imageLen = d.X * d.Y * 4
- }
- err = binary.Write(w, enc, uint32(imageLen+8))
- if err != nil {
- return err
- }
- case cDeflate:
- dst = zlib.NewWriter(&buf)
- }
-
- pr := uint32(prNone)
- photometricInterpretation := uint32(pRGB)
- samplesPerPixel := uint32(4)
- bitsPerSample := []uint32{8, 8, 8, 8}
- extraSamples := uint32(0)
- colorMap := []uint32{}
-
- if predictor {
- pr = prHorizontal
- }
- switch m := m.(type) {
- case *image.Paletted:
- photometricInterpretation = pPaletted
- samplesPerPixel = 1
- bitsPerSample = []uint32{8}
- colorMap = make([]uint32, 256*3)
- for i := 0; i < 256 && i < len(m.Palette); i++ {
- r, g, b, _ := m.Palette[i].RGBA()
- colorMap[i+0*256] = uint32(r)
- colorMap[i+1*256] = uint32(g)
- colorMap[i+2*256] = uint32(b)
- }
- err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.Gray:
- photometricInterpretation = pBlackIsZero
- samplesPerPixel = 1
- bitsPerSample = []uint32{8}
- err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.Gray16:
- photometricInterpretation = pBlackIsZero
- samplesPerPixel = 1
- bitsPerSample = []uint32{16}
- err = encodeGray16(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.NRGBA:
- extraSamples = 2 // Unassociated alpha.
- err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.NRGBA64:
- extraSamples = 2 // Unassociated alpha.
- bitsPerSample = []uint32{16, 16, 16, 16}
- err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.RGBA:
- extraSamples = 1 // Associated alpha.
- err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- case *image.RGBA64:
- extraSamples = 1 // Associated alpha.
- bitsPerSample = []uint32{16, 16, 16, 16}
- err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor)
- default:
- extraSamples = 1 // Associated alpha.
- err = encode(dst, m, predictor)
- }
- if err != nil {
- return err
- }
-
- if compression != cNone {
- if err = dst.(io.Closer).Close(); err != nil {
- return err
- }
- imageLen = buf.Len()
- if err = binary.Write(w, enc, uint32(imageLen+8)); err != nil {
- return err
- }
- if _, err = buf.WriteTo(w); err != nil {
- return err
- }
- }
-
- ifd := []ifdEntry{
- {tImageWidth, dtShort, []uint32{uint32(d.X)}},
- {tImageLength, dtShort, []uint32{uint32(d.Y)}},
- {tBitsPerSample, dtShort, bitsPerSample},
- {tCompression, dtShort, []uint32{compression}},
- {tPhotometricInterpretation, dtShort, []uint32{photometricInterpretation}},
- {tStripOffsets, dtLong, []uint32{8}},
- {tSamplesPerPixel, dtShort, []uint32{samplesPerPixel}},
- {tRowsPerStrip, dtShort, []uint32{uint32(d.Y)}},
- {tStripByteCounts, dtLong, []uint32{uint32(imageLen)}},
- // There is currently no support for storing the image
- // resolution, so give a bogus value of 72x72 dpi.
- {tXResolution, dtRational, []uint32{72, 1}},
- {tYResolution, dtRational, []uint32{72, 1}},
- {tResolutionUnit, dtShort, []uint32{resPerInch}},
- }
- if pr != prNone {
- ifd = append(ifd, ifdEntry{tPredictor, dtShort, []uint32{pr}})
- }
- if len(colorMap) != 0 {
- ifd = append(ifd, ifdEntry{tColorMap, dtShort, colorMap})
- }
- if extraSamples > 0 {
- ifd = append(ifd, ifdEntry{tExtraSamples, dtShort, []uint32{extraSamples}})
- }
-
- return writeIFD(w, imageLen+8, ifd)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml
deleted file mode 100644
index 44aa48b87..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: go
-go:
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - tip
-go_import_path: gopkg.in/asn-ber.v1
-install:
- - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
- - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
- - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
- - go build -v ./...
-script:
- - go test -v -cover ./...
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE
deleted file mode 100644
index 744875676..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md
deleted file mode 100644
index e3a9560d6..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-[![GoDoc](https://godoc.org/gopkg.in/asn1-ber.v1?status.svg)](https://godoc.org/gopkg.in/asn1-ber.v1) [![Build Status](https://travis-ci.org/go-asn1-ber/asn1-ber.svg)](https://travis-ci.org/go-asn1-ber/asn1-ber)
-
-
-ASN1 BER Encoding / Decoding Library for the GO programming language.
----------------------------------------------------------------------
-
-Required libraries:
- None
-
-Working:
- Very basic encoding / decoding needed for LDAP protocol
-
-Tests Implemented:
- A few
-
-TODO:
- Fix all encoding / decoding to conform to ASN1 BER spec
- Implement Tests / Benchmarks
-
----
-
-The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
-The design is licensed under the Creative Commons 3.0 Attributions license.
-Read this article for more details: http://blog.golang.org/gopher
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go
deleted file mode 100644
index 25cc921be..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go
+++ /dev/null
@@ -1,504 +0,0 @@
-package ber
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
-)
-
-type Packet struct {
- Identifier
- Value interface{}
- ByteValue []byte
- Data *bytes.Buffer
- Children []*Packet
- Description string
-}
-
-type Identifier struct {
- ClassType Class
- TagType Type
- Tag Tag
-}
-
-type Tag uint64
-
-const (
- TagEOC Tag = 0x00
- TagBoolean Tag = 0x01
- TagInteger Tag = 0x02
- TagBitString Tag = 0x03
- TagOctetString Tag = 0x04
- TagNULL Tag = 0x05
- TagObjectIdentifier Tag = 0x06
- TagObjectDescriptor Tag = 0x07
- TagExternal Tag = 0x08
- TagRealFloat Tag = 0x09
- TagEnumerated Tag = 0x0a
- TagEmbeddedPDV Tag = 0x0b
- TagUTF8String Tag = 0x0c
- TagRelativeOID Tag = 0x0d
- TagSequence Tag = 0x10
- TagSet Tag = 0x11
- TagNumericString Tag = 0x12
- TagPrintableString Tag = 0x13
- TagT61String Tag = 0x14
- TagVideotexString Tag = 0x15
- TagIA5String Tag = 0x16
- TagUTCTime Tag = 0x17
- TagGeneralizedTime Tag = 0x18
- TagGraphicString Tag = 0x19
- TagVisibleString Tag = 0x1a
- TagGeneralString Tag = 0x1b
- TagUniversalString Tag = 0x1c
- TagCharacterString Tag = 0x1d
- TagBMPString Tag = 0x1e
- TagBitmask Tag = 0x1f // xxx11111b
-
- // HighTag indicates the start of a high-tag byte sequence
- HighTag Tag = 0x1f // xxx11111b
- // HighTagContinueBitmask indicates the high-tag byte sequence should continue
- HighTagContinueBitmask Tag = 0x80 // 10000000b
- // HighTagValueBitmask obtains the tag value from a high-tag byte sequence byte
- HighTagValueBitmask Tag = 0x7f // 01111111b
-)
-
-const (
- // LengthLongFormBitmask is the mask to apply to the length byte to see if a long-form byte sequence is used
- LengthLongFormBitmask = 0x80
- // LengthValueBitmask is the mask to apply to the length byte to get the number of bytes in the long-form byte sequence
- LengthValueBitmask = 0x7f
-
- // LengthIndefinite is returned from readLength to indicate an indefinite length
- LengthIndefinite = -1
-)
-
-var tagMap = map[Tag]string{
- TagEOC: "EOC (End-of-Content)",
- TagBoolean: "Boolean",
- TagInteger: "Integer",
- TagBitString: "Bit String",
- TagOctetString: "Octet String",
- TagNULL: "NULL",
- TagObjectIdentifier: "Object Identifier",
- TagObjectDescriptor: "Object Descriptor",
- TagExternal: "External",
- TagRealFloat: "Real (float)",
- TagEnumerated: "Enumerated",
- TagEmbeddedPDV: "Embedded PDV",
- TagUTF8String: "UTF8 String",
- TagRelativeOID: "Relative-OID",
- TagSequence: "Sequence and Sequence of",
- TagSet: "Set and Set OF",
- TagNumericString: "Numeric String",
- TagPrintableString: "Printable String",
- TagT61String: "T61 String",
- TagVideotexString: "Videotex String",
- TagIA5String: "IA5 String",
- TagUTCTime: "UTC Time",
- TagGeneralizedTime: "Generalized Time",
- TagGraphicString: "Graphic String",
- TagVisibleString: "Visible String",
- TagGeneralString: "General String",
- TagUniversalString: "Universal String",
- TagCharacterString: "Character String",
- TagBMPString: "BMP String",
-}
-
-type Class uint8
-
-const (
- ClassUniversal Class = 0 // 00xxxxxxb
- ClassApplication Class = 64 // 01xxxxxxb
- ClassContext Class = 128 // 10xxxxxxb
- ClassPrivate Class = 192 // 11xxxxxxb
- ClassBitmask Class = 192 // 11xxxxxxb
-)
-
-var ClassMap = map[Class]string{
- ClassUniversal: "Universal",
- ClassApplication: "Application",
- ClassContext: "Context",
- ClassPrivate: "Private",
-}
-
-type Type uint8
-
-const (
- TypePrimitive Type = 0 // xx0xxxxxb
- TypeConstructed Type = 32 // xx1xxxxxb
- TypeBitmask Type = 32 // xx1xxxxxb
-)
-
-var TypeMap = map[Type]string{
- TypePrimitive: "Primitive",
- TypeConstructed: "Constructed",
-}
-
-var Debug bool = false
-
-func PrintBytes(out io.Writer, buf []byte, indent string) {
- data_lines := make([]string, (len(buf)/30)+1)
- num_lines := make([]string, (len(buf)/30)+1)
-
- for i, b := range buf {
- data_lines[i/30] += fmt.Sprintf("%02x ", b)
- num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
- }
-
- for i := 0; i < len(data_lines); i++ {
- out.Write([]byte(indent + data_lines[i] + "\n"))
- out.Write([]byte(indent + num_lines[i] + "\n\n"))
- }
-}
-
-func PrintPacket(p *Packet) {
- printPacket(os.Stdout, p, 0, false)
-}
-
-func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
- indent_str := ""
-
- for len(indent_str) != indent {
- indent_str += " "
- }
-
- class_str := ClassMap[p.ClassType]
-
- tagtype_str := TypeMap[p.TagType]
-
- tag_str := fmt.Sprintf("0x%02X", p.Tag)
-
- if p.ClassType == ClassUniversal {
- tag_str = tagMap[p.Tag]
- }
-
- value := fmt.Sprint(p.Value)
- description := ""
-
- if p.Description != "" {
- description = p.Description + ": "
- }
-
- fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
-
- if printBytes {
- PrintBytes(out, p.Bytes(), indent_str)
- }
-
- for _, child := range p.Children {
- printPacket(out, child, indent+1, printBytes)
- }
-}
-
-// ReadPacket reads a single Packet from the reader
-func ReadPacket(reader io.Reader) (*Packet, error) {
- p, _, err := readPacket(reader)
- if err != nil {
- return nil, err
- }
- return p, nil
-}
-
-func DecodeString(data []byte) string {
- return string(data)
-}
-
-func parseInt64(bytes []byte) (ret int64, err error) {
- if len(bytes) > 8 {
- // We'll overflow an int64 in this case.
- err = fmt.Errorf("integer too large")
- return
- }
- for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
- ret <<= 8
- ret |= int64(bytes[bytesRead])
- }
-
- // Shift up and down in order to sign extend the result.
- ret <<= 64 - uint8(len(bytes))*8
- ret >>= 64 - uint8(len(bytes))*8
- return
-}
-
-func encodeInteger(i int64) []byte {
- n := int64Length(i)
- out := make([]byte, n)
-
- var j int
- for ; n > 0; n-- {
- out[j] = (byte(i >> uint((n-1)*8)))
- j++
- }
-
- return out
-}
-
-func int64Length(i int64) (numBytes int) {
- numBytes = 1
-
- for i > 127 {
- numBytes++
- i >>= 8
- }
-
- for i < -128 {
- numBytes++
- i >>= 8
- }
-
- return
-}
-
-// DecodePacket decodes the given bytes into a single Packet
-// If a decode error is encountered, nil is returned.
-func DecodePacket(data []byte) *Packet {
- p, _, _ := readPacket(bytes.NewBuffer(data))
-
- return p
-}
-
-// DecodePacketErr decodes the given bytes into a single Packet
-// If a decode error is encountered, nil is returned
-func DecodePacketErr(data []byte) (*Packet, error) {
- p, _, err := readPacket(bytes.NewBuffer(data))
- if err != nil {
- return nil, err
- }
- return p, nil
-}
-
-// readPacket reads a single Packet from the reader, returning the number of bytes read
-func readPacket(reader io.Reader) (*Packet, int, error) {
- identifier, length, read, err := readHeader(reader)
- if err != nil {
- return nil, read, err
- }
-
- p := &Packet{
- Identifier: identifier,
- }
-
- p.Data = new(bytes.Buffer)
- p.Children = make([]*Packet, 0, 2)
- p.Value = nil
-
- if p.TagType == TypeConstructed {
- // TODO: if universal, ensure tag type is allowed to be constructed
-
- // Track how much content we've read
- contentRead := 0
- for {
- if length != LengthIndefinite {
- // End if we've read what we've been told to
- if contentRead == length {
- break
- }
- // Detect if a packet boundary didn't fall on the expected length
- if contentRead > length {
- return nil, read, fmt.Errorf("expected to read %d bytes, read %d", length, contentRead)
- }
- }
-
- // Read the next packet
- child, r, err := readPacket(reader)
- if err != nil {
- return nil, read, err
- }
- contentRead += r
- read += r
-
- // Test is this is the EOC marker for our packet
- if isEOCPacket(child) {
- if length == LengthIndefinite {
- break
- }
- return nil, read, errors.New("eoc child not allowed with definite length")
- }
-
- // Append and continue
- p.AppendChild(child)
- }
- return p, read, nil
- }
-
- if length == LengthIndefinite {
- return nil, read, errors.New("indefinite length used with primitive type")
- }
-
- // Read definite-length content
- content := make([]byte, length, length)
- if length > 0 {
- _, err := io.ReadFull(reader, content)
- if err != nil {
- if err == io.EOF {
- return nil, read, io.ErrUnexpectedEOF
- }
- return nil, read, err
- }
- read += length
- }
-
- if p.ClassType == ClassUniversal {
- p.Data.Write(content)
- p.ByteValue = content
-
- switch p.Tag {
- case TagEOC:
- case TagBoolean:
- val, _ := parseInt64(content)
-
- p.Value = val != 0
- case TagInteger:
- p.Value, _ = parseInt64(content)
- case TagBitString:
- case TagOctetString:
- // the actual string encoding is not known here
- // (e.g. for LDAP content is already an UTF8-encoded
- // string). Return the data without further processing
- p.Value = DecodeString(content)
- case TagNULL:
- case TagObjectIdentifier:
- case TagObjectDescriptor:
- case TagExternal:
- case TagRealFloat:
- case TagEnumerated:
- p.Value, _ = parseInt64(content)
- case TagEmbeddedPDV:
- case TagUTF8String:
- p.Value = DecodeString(content)
- case TagRelativeOID:
- case TagSequence:
- case TagSet:
- case TagNumericString:
- case TagPrintableString:
- p.Value = DecodeString(content)
- case TagT61String:
- case TagVideotexString:
- case TagIA5String:
- case TagUTCTime:
- case TagGeneralizedTime:
- case TagGraphicString:
- case TagVisibleString:
- case TagGeneralString:
- case TagUniversalString:
- case TagCharacterString:
- case TagBMPString:
- }
- } else {
- p.Data.Write(content)
- }
-
- return p, read, nil
-}
-
-func (p *Packet) Bytes() []byte {
- var out bytes.Buffer
-
- out.Write(encodeIdentifier(p.Identifier))
- out.Write(encodeLength(p.Data.Len()))
- out.Write(p.Data.Bytes())
-
- return out.Bytes()
-}
-
-func (p *Packet) AppendChild(child *Packet) {
- p.Data.Write(child.Bytes())
- p.Children = append(p.Children, child)
-}
-
-func Encode(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
- p := new(Packet)
-
- p.ClassType = ClassType
- p.TagType = TagType
- p.Tag = Tag
- p.Data = new(bytes.Buffer)
-
- p.Children = make([]*Packet, 0, 2)
-
- p.Value = Value
- p.Description = Description
-
- if Value != nil {
- v := reflect.ValueOf(Value)
-
- if ClassType == ClassUniversal {
- switch Tag {
- case TagOctetString:
- sv, ok := v.Interface().(string)
-
- if ok {
- p.Data.Write([]byte(sv))
- }
- }
- }
- }
-
- return p
-}
-
-func NewSequence(Description string) *Packet {
- return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description)
-}
-
-func NewBoolean(ClassType Class, TagType Type, Tag Tag, Value bool, Description string) *Packet {
- intValue := int64(0)
-
- if Value {
- intValue = 1
- }
-
- p := Encode(ClassType, TagType, Tag, nil, Description)
-
- p.Value = Value
- p.Data.Write(encodeInteger(intValue))
-
- return p
-}
-
-func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
- p := Encode(ClassType, TagType, Tag, nil, Description)
-
- p.Value = Value
- switch v := Value.(type) {
- case int:
- p.Data.Write(encodeInteger(int64(v)))
- case uint:
- p.Data.Write(encodeInteger(int64(v)))
- case int64:
- p.Data.Write(encodeInteger(v))
- case uint64:
- // TODO : check range or add encodeUInt...
- p.Data.Write(encodeInteger(int64(v)))
- case int32:
- p.Data.Write(encodeInteger(int64(v)))
- case uint32:
- p.Data.Write(encodeInteger(int64(v)))
- case int16:
- p.Data.Write(encodeInteger(int64(v)))
- case uint16:
- p.Data.Write(encodeInteger(int64(v)))
- case int8:
- p.Data.Write(encodeInteger(int64(v)))
- case uint8:
- p.Data.Write(encodeInteger(int64(v)))
- default:
- // TODO : add support for big.Int ?
- panic(fmt.Sprintf("Invalid type %T, expected {u|}int{64|32|16|8}", v))
- }
-
- return p
-}
-
-func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet {
- p := Encode(ClassType, TagType, Tag, nil, Description)
-
- p.Value = Value
- p.Data.Write([]byte(Value))
-
- return p
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go
deleted file mode 100644
index 1858b74b6..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package ber
-
-func encodeUnsignedInteger(i uint64) []byte {
- n := uint64Length(i)
- out := make([]byte, n)
-
- var j int
- for ; n > 0; n-- {
- out[j] = (byte(i >> uint((n-1)*8)))
- j++
- }
-
- return out
-}
-
-func uint64Length(i uint64) (numBytes int) {
- numBytes = 1
-
- for i > 255 {
- numBytes++
- i >>= 8
- }
-
- return
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go
deleted file mode 100644
index 123744e9b..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package ber
-
-import (
- "errors"
- "io"
-)
-
-func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
- if i, c, err := readIdentifier(reader); err != nil {
- return Identifier{}, 0, read, err
- } else {
- identifier = i
- read += c
- }
-
- if l, c, err := readLength(reader); err != nil {
- return Identifier{}, 0, read, err
- } else {
- length = l
- read += c
- }
-
- // Validate length type with identifier (x.600, 8.1.3.2.a)
- if length == LengthIndefinite && identifier.TagType == TypePrimitive {
- return Identifier{}, 0, read, errors.New("indefinite length used with primitive type")
- }
-
- return identifier, length, read, nil
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go
deleted file mode 100644
index f7672a844..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package ber
-
-import (
- "errors"
- "fmt"
- "io"
- "math"
-)
-
-func readIdentifier(reader io.Reader) (Identifier, int, error) {
- identifier := Identifier{}
- read := 0
-
- // identifier byte
- b, err := readByte(reader)
- if err != nil {
- if Debug {
- fmt.Printf("error reading identifier byte: %v\n", err)
- }
- return Identifier{}, read, err
- }
- read++
-
- identifier.ClassType = Class(b) & ClassBitmask
- identifier.TagType = Type(b) & TypeBitmask
-
- if tag := Tag(b) & TagBitmask; tag != HighTag {
- // short-form tag
- identifier.Tag = tag
- return identifier, read, nil
- }
-
- // high-tag-number tag
- tagBytes := 0
- for {
- b, err := readByte(reader)
- if err != nil {
- if Debug {
- fmt.Printf("error reading high-tag-number tag byte %d: %v\n", tagBytes, err)
- }
- return Identifier{}, read, err
- }
- tagBytes++
- read++
-
- // Lowest 7 bits get appended to the tag value (x.690, 8.1.2.4.2.b)
- identifier.Tag <<= 7
- identifier.Tag |= Tag(b) & HighTagValueBitmask
-
- // First byte may not be all zeros (x.690, 8.1.2.4.2.c)
- if tagBytes == 1 && identifier.Tag == 0 {
- return Identifier{}, read, errors.New("invalid first high-tag-number tag byte")
- }
- // Overflow of int64
- // TODO: support big int tags?
- if tagBytes > 9 {
- return Identifier{}, read, errors.New("high-tag-number tag overflow")
- }
-
- // Top bit of 0 means this is the last byte in the high-tag-number tag (x.690, 8.1.2.4.2.a)
- if Tag(b)&HighTagContinueBitmask == 0 {
- break
- }
- }
-
- return identifier, read, nil
-}
-
-func encodeIdentifier(identifier Identifier) []byte {
- b := []byte{0x0}
- b[0] |= byte(identifier.ClassType)
- b[0] |= byte(identifier.TagType)
-
- if identifier.Tag < HighTag {
- // Short-form
- b[0] |= byte(identifier.Tag)
- } else {
- // high-tag-number
- b[0] |= byte(HighTag)
-
- tag := identifier.Tag
-
- highBit := uint(63)
- for {
- if tag&(1<<highBit) != 0 {
- break
- }
- highBit--
- }
-
- tagBytes := int(math.Ceil(float64(highBit) / 7.0))
- for i := tagBytes - 1; i >= 0; i-- {
- offset := uint(i) * 7
- mask := Tag(0x7f) << offset
- tagByte := (tag & mask) >> offset
- if i != 0 {
- tagByte |= 0x80
- }
- b = append(b, byte(tagByte))
- }
- }
- return b
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go
deleted file mode 100644
index 8e2ae4ddd..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package ber
-
-import (
- "errors"
- "fmt"
- "io"
-)
-
-func readLength(reader io.Reader) (length int, read int, err error) {
- // length byte
- b, err := readByte(reader)
- if err != nil {
- if Debug {
- fmt.Printf("error reading length byte: %v\n", err)
- }
- return 0, 0, err
- }
- read++
-
- switch {
- case b == 0xFF:
- // Invalid 0xFF (x.600, 8.1.3.5.c)
- return 0, read, errors.New("invalid length byte 0xff")
-
- case b == LengthLongFormBitmask:
- // Indefinite form, we have to decode packets until we encounter an EOC packet (x.600, 8.1.3.6)
- length = LengthIndefinite
-
- case b&LengthLongFormBitmask == 0:
- // Short definite form, extract the length from the bottom 7 bits (x.600, 8.1.3.4)
- length = int(b) & LengthValueBitmask
-
- case b&LengthLongFormBitmask != 0:
- // Long definite form, extract the number of length bytes to follow from the bottom 7 bits (x.600, 8.1.3.5.b)
- lengthBytes := int(b) & LengthValueBitmask
- // Protect against overflow
- // TODO: support big int length?
- if lengthBytes > 8 {
- return 0, read, errors.New("long-form length overflow")
- }
- for i := 0; i < lengthBytes; i++ {
- b, err = readByte(reader)
- if err != nil {
- if Debug {
- fmt.Printf("error reading long-form length byte %d: %v\n", i, err)
- }
- return 0, read, err
- }
- read++
-
- // x.600, 8.1.3.5
- length <<= 8
- length |= int(b)
- }
-
- default:
- return 0, read, errors.New("invalid length byte")
- }
-
- return length, read, nil
-}
-
-func encodeLength(length int) []byte {
- length_bytes := encodeUnsignedInteger(uint64(length))
- if length > 127 || len(length_bytes) > 1 {
- longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
- longFormBytes = append(longFormBytes, length_bytes...)
- length_bytes = longFormBytes
- }
- return length_bytes
-}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber
deleted file mode 100644
index 5c6ba1c6a..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber
+++ /dev/null
@@ -1 +0,0 @@
-Ÿÿÿÿÿÿÿÿÿÿ@ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber
deleted file mode 100644
index f733125d4..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber
+++ /dev/null
@@ -1 +0,0 @@
- ƒÿÿÿû \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber
deleted file mode 100644
index cc4a609c8..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber
+++ /dev/null
@@ -1 +0,0 @@
-  015625 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber
deleted file mode 100644
index dbb538d69..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber
+++ /dev/null
@@ -1 +0,0 @@
- I \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber
deleted file mode 100644
index f4f438e0d..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber
deleted file mode 100644
index b6f2fd3a4..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber
deleted file mode 100644
index 3d6da6764..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber
+++ /dev/null
@@ -1 +0,0 @@
- ƒ ÿÿÿÿÿÿÿû \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber
deleted file mode 100644
index 68634f5f3..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber
+++ /dev/null
@@ -1 +0,0 @@
- €û \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber
deleted file mode 100644
index adb9e3320..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber
+++ /dev/null
@@ -1 +0,0 @@
- ¯ þÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber
deleted file mode 100644
index fb6843f7f..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber
+++ /dev/null
@@ -1 +0,0 @@
-ÿð \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber
deleted file mode 100644
index 03afaa5de..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber
deleted file mode 100644
index 7e785773c..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber
+++ /dev/null
@@ -1 +0,0 @@
-Ÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber
deleted file mode 100644
index a976464b9..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber
deleted file mode 100644
index d6c2f9aa7..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber
+++ /dev/null
@@ -1 +0,0 @@
-€€Q€€ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber
deleted file mode 100644
index d1d70afab..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber
+++ /dev/null
@@ -1 +0,0 @@
-ÿÿÿÿÿÿÿÿÿÿ… \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber
deleted file mode 100644
index 0e8d18f62..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber
+++ /dev/null
@@ -1 +0,0 @@
-ÿÿÿÿÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber
deleted file mode 100644
index 10565aefa..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber
+++ /dev/null
@@ -1 +0,0 @@
-Î`†HˆŸO …îåJ…ä¿c‹Û/ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber
deleted file mode 100644
index 1e1140524..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber
deleted file mode 100644
index d28653b3b..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber
deleted file mode 100644
index c8c781144..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber
deleted file mode 100644
index 415fe23ed..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber
+++ /dev/null
@@ -1 +0,0 @@
-ÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber
deleted file mode 100644
index 4076f4487..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber
deleted file mode 100644
index c05c900b6..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber
+++ /dev/null
@@ -1 +0,0 @@
-Ÿÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber
deleted file mode 100644
index 72bcf80f4..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber
deleted file mode 100644
index 1fcc4f254..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber
deleted file mode 100644
index 19b3e940a..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber
deleted file mode 100644
index 6ea70c4d2..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber
deleted file mode 100644
index 61337095d..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber
deleted file mode 100644
index d27eb301a..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber
deleted file mode 100644
index e5baaeacd..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber
deleted file mode 100644
index d0b1cfbe1..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber
deleted file mode 100644
index 090bce74b..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber
deleted file mode 100644
index d9d01199b..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber
deleted file mode 100644
index 2b888baac..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber
+++ /dev/null
@@ -1 +0,0 @@
-Ÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber
deleted file mode 100644
index 15294a501..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber
deleted file mode 100644
index 276836b65..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber
deleted file mode 100644
index 21cbfd10f..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber
deleted file mode 100644
index 98dbd7419..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber
+++ /dev/null
@@ -1 +0,0 @@
-$ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber
deleted file mode 100644
index d825e1ad7..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber
deleted file mode 100644
index 7b861b02c..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber
deleted file mode 100644
index e78deee34..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber
deleted file mode 100644
index 190bb86f6..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber
deleted file mode 100644
index f7f111ae6..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber
deleted file mode 100644
index 45e0a0093..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber
+++ /dev/null
@@ -1 +0,0 @@
-Ÿÿÿÿÿÿÿÿÿ@ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber
deleted file mode 100644
index cee1aaf0c..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber
+++ /dev/null
@@ -1 +0,0 @@
- +0.E-5 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber
deleted file mode 100644
index d5ae68572..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber
+++ /dev/null
@@ -1 +0,0 @@
- -0.E-5 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber
deleted file mode 100644
index cb32a09cb..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber
deleted file mode 100644
index 50b43a510..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber
+++ /dev/null
@@ -1 +0,0 @@
- ¼þ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go
deleted file mode 100644
index 3e56b66c8..000000000
--- a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package ber
-
-import "io"
-
-func readByte(reader io.Reader) (byte, error) {
- bytes := make([]byte, 1, 1)
- _, err := io.ReadFull(reader, bytes)
- if err != nil {
- if err == io.EOF {
- return 0, io.ErrUnexpectedEOF
- }
- return 0, err
- }
- return bytes[0], nil
-}
-
-func isEOCPacket(p *Packet) bool {
- return p != nil &&
- p.Tag == TagEOC &&
- p.ClassType == ClassUniversal &&
- p.TagType == TypePrimitive &&
- len(p.ByteValue) == 0 &&
- len(p.Children) == 0
-}
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.gitignore b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.gitignore
deleted file mode 100644
index 4cd0cbaf4..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-# Setup a Global .gitignore for OS and editor generated files:
-# https://help.github.com/articles/ignoring-files
-# git config --global core.excludesfile ~/.gitignore_global
-
-.vagrant
-*.sublime-project
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.travis.yml b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.travis.yml
deleted file mode 100644
index 1b5151f12..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-sudo: false
-language: go
-
-go:
- - 1.5.1
-
-before_script:
- - go get -u github.com/golang/lint/golint
-
-after_script:
- - test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
- - test -z "$(golint ./... | tee /dev/stderr)"
- - go vet ./...
-
-os:
- - linux
- - osx
-
-notifications:
- email: false
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/AUTHORS b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/AUTHORS
deleted file mode 100644
index 763b853c3..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/AUTHORS
+++ /dev/null
@@ -1,39 +0,0 @@
-# Names should be added to this file as
-# Name or Organization <email address>
-# The email address is not required for organizations.
-
-# You can update this list using the following command:
-#
-# $ git shortlog -se | awk '{print $2 " " $3 " " $4}'
-
-# Please keep the list sorted.
-
-Adrien Bustany <adrien@bustany.org>
-Caleb Spare <cespare@gmail.com>
-Case Nelson <case@teammating.com>
-Chris Howey <chris@howey.me> <howeyc@gmail.com>
-Christoffer Buchholz <christoffer.buchholz@gmail.com>
-Daniel Wagner-Hall <dawagner@gmail.com>
-Dave Cheney <dave@cheney.net>
-Evan Phoenix <evan@fallingsnow.net>
-Francisco Souza <f@souza.cc>
-Hari haran <hariharan.uno@gmail.com>
-John C Barstow
-Kelvin Fo <vmirage@gmail.com>
-Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
-Matt Layher <mdlayher@gmail.com>
-Nathan Youngman <git@nathany.com>
-Paul Hammond <paul@paulhammond.org>
-Pieter Droogendijk <pieter@binky.org.uk>
-Pursuit92 <JoshChase@techpursuit.net>
-Riku Voipio <riku.voipio@linaro.org>
-Rob Figueiredo <robfig@gmail.com>
-Soge Zhang <zhssoge@gmail.com>
-Tilak Sharma <tilaks@google.com>
-Travis Cline <travis.cline@gmail.com>
-Tudor Golubenco <tudor.g@gmail.com>
-Yukang <moorekang@gmail.com>
-bronze1man <bronze1man@gmail.com>
-debrando <denis.brandolini@gmail.com>
-henrikedwards <henrik.edwards@gmail.com>
-é“å“¥ <guotie.9@gmail.com>
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CHANGELOG.md b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CHANGELOG.md
deleted file mode 100644
index 4e6672702..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CHANGELOG.md
+++ /dev/null
@@ -1,274 +0,0 @@
-# Changelog
-
-## v1.2.5 / 2015-10-17
-
-* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/go-fsnotify/fsnotify/pull/100) (thanks @suihkulokki)
-* inotify: fix path leaks [#73](https://github.com/go-fsnotify/fsnotify/pull/73) (thanks @chamaken)
-* kqueue: watch for rename events on subdirectories [#83](https://github.com/go-fsnotify/fsnotify/pull/83) (thanks @guotie)
-* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/go-fsnotify/fsnotify/pull/101) (thanks @illicitonion)
-
-## v1.2.1 / 2015-10-14
-
-* kqueue: don't watch named pipes [#98](https://github.com/go-fsnotify/fsnotify/pull/98) (thanks @evanphx)
-
-## v1.2.0 / 2015-02-08
-
-* inotify: use epoll to wake up readEvents [#66](https://github.com/go-fsnotify/fsnotify/pull/66) (thanks @PieterD)
-* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/go-fsnotify/fsnotify/pull/63) (thanks @PieterD)
-* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/go-fsnotify/fsnotify/issues/59)
-
-## v1.1.1 / 2015-02-05
-
-* inotify: Retry read on EINTR [#61](https://github.com/go-fsnotify/fsnotify/issues/61) (thanks @PieterD)
-
-## v1.1.0 / 2014-12-12
-
-* kqueue: rework internals [#43](https://github.com/go-fsnotify/fsnotify/pull/43)
- * add low-level functions
- * only need to store flags on directories
- * less mutexes [#13](https://github.com/go-fsnotify/fsnotify/issues/13)
- * done can be an unbuffered channel
- * remove calls to os.NewSyscallError
-* More efficient string concatenation for Event.String() [#52](https://github.com/go-fsnotify/fsnotify/pull/52) (thanks @mdlayher)
-* kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/go-fsnotify/fsnotify/issues/48)
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/go-fsnotify/fsnotify/issues/51)
-
-## v1.0.4 / 2014-09-07
-
-* kqueue: add dragonfly to the build tags.
-* Rename source code files, rearrange code so exported APIs are at the top.
-* Add done channel to example code. [#37](https://github.com/go-fsnotify/fsnotify/pull/37) (thanks @chenyukang)
-
-## v1.0.3 / 2014-08-19
-
-* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/go-fsnotify/fsnotify/issues/36)
-
-## v1.0.2 / 2014-08-17
-
-* [Fix] Missing create events on OS X. [#14](https://github.com/go-fsnotify/fsnotify/issues/14) (thanks @zhsso)
-* [Fix] Make ./path and path equivalent. (thanks @zhsso)
-
-## v1.0.0 / 2014-08-15
-
-* [API] Remove AddWatch on Windows, use Add.
-* Improve documentation for exported identifiers. [#30](https://github.com/go-fsnotify/fsnotify/issues/30)
-* Minor updates based on feedback from golint.
-
-## dev / 2014-07-09
-
-* Moved to [github.com/go-fsnotify/fsnotify](https://github.com/go-fsnotify/fsnotify).
-* Use os.NewSyscallError instead of returning errno (thanks @hariharan-uno)
-
-## dev / 2014-07-04
-
-* kqueue: fix incorrect mutex used in Close()
-* Update example to demonstrate usage of Op.
-
-## dev / 2014-06-28
-
-* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/go-fsnotify/fsnotify/issues/4)
-* Fix for String() method on Event (thanks Alex Brainman)
-* Don't build on Plan 9 or Solaris (thanks @4ad)
-
-## dev / 2014-06-21
-
-* Events channel of type Event rather than *Event.
-* [internal] use syscall constants directly for inotify and kqueue.
-* [internal] kqueue: rename events to kevents and fileEvent to event.
-
-## dev / 2014-06-19
-
-* Go 1.3+ required on Windows (uses syscall.ERROR_MORE_DATA internally).
-* [internal] remove cookie from Event struct (unused).
-* [internal] Event struct has the same definition across every OS.
-* [internal] remove internal watch and removeWatch methods.
-
-## dev / 2014-06-12
-
-* [API] Renamed Watch() to Add() and RemoveWatch() to Remove().
-* [API] Pluralized channel names: Events and Errors.
-* [API] Renamed FileEvent struct to Event.
-* [API] Op constants replace methods like IsCreate().
-
-## dev / 2014-06-12
-
-* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
-
-## dev / 2014-05-23
-
-* [API] Remove current implementation of WatchFlags.
- * current implementation doesn't take advantage of OS for efficiency
- * provides little benefit over filtering events as they are received, but has extra bookkeeping and mutexes
- * no tests for the current implementation
- * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195)
-
-## v0.9.3 / 2014-12-31
-
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/go-fsnotify/fsnotify/issues/51)
-
-## v0.9.2 / 2014-08-17
-
-* [Backport] Fix missing create events on OS X. [#14](https://github.com/go-fsnotify/fsnotify/issues/14) (thanks @zhsso)
-
-## v0.9.1 / 2014-06-12
-
-* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
-
-## v0.9.0 / 2014-01-17
-
-* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany)
-* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare)
-* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library.
-
-## v0.8.12 / 2013-11-13
-
-* [API] Remove FD_SET and friends from Linux adapter
-
-## v0.8.11 / 2013-11-02
-
-* [Doc] Add Changelog [#72][] (thanks @nathany)
-* [Doc] Spotlight and double modify events on OS X [#62][] (reported by @paulhammond)
-
-## v0.8.10 / 2013-10-19
-
-* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott)
-* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer)
-* [Doc] specify OS-specific limits in README (thanks @debrando)
-
-## v0.8.9 / 2013-09-08
-
-* [Doc] Contributing (thanks @nathany)
-* [Doc] update package path in example code [#63][] (thanks @paulhammond)
-* [Doc] GoCI badge in README (Linux only) [#60][]
-* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany)
-
-## v0.8.8 / 2013-06-17
-
-* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie)
-
-## v0.8.7 / 2013-06-03
-
-* [API] Make syscall flags internal
-* [Fix] inotify: ignore event changes
-* [Fix] race in symlink test [#45][] (reported by @srid)
-* [Fix] tests on Windows
-* lower case error messages
-
-## v0.8.6 / 2013-05-23
-
-* kqueue: Use EVT_ONLY flag on Darwin
-* [Doc] Update README with full example
-
-## v0.8.5 / 2013-05-09
-
-* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg)
-
-## v0.8.4 / 2013-04-07
-
-* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz)
-
-## v0.8.3 / 2013-03-13
-
-* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin)
-* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin)
-
-## v0.8.2 / 2013-02-07
-
-* [Doc] add Authors
-* [Fix] fix data races for map access [#29][] (thanks @fsouza)
-
-## v0.8.1 / 2013-01-09
-
-* [Fix] Windows path separators
-* [Doc] BSD License
-
-## v0.8.0 / 2012-11-09
-
-* kqueue: directory watching improvements (thanks @vmirage)
-* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto)
-* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr)
-
-## v0.7.4 / 2012-10-09
-
-* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji)
-* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig)
-* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig)
-* [Fix] kqueue: modify after recreation of file
-
-## v0.7.3 / 2012-09-27
-
-* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage)
-* [Fix] kqueue: no longer get duplicate CREATE events
-
-## v0.7.2 / 2012-09-01
-
-* kqueue: events for created directories
-
-## v0.7.1 / 2012-07-14
-
-* [Fix] for renaming files
-
-## v0.7.0 / 2012-07-02
-
-* [Feature] FSNotify flags
-* [Fix] inotify: Added file name back to event path
-
-## v0.6.0 / 2012-06-06
-
-* kqueue: watch files after directory created (thanks @tmc)
-
-## v0.5.1 / 2012-05-22
-
-* [Fix] inotify: remove all watches before Close()
-
-## v0.5.0 / 2012-05-03
-
-* [API] kqueue: return errors during watch instead of sending over channel
-* kqueue: match symlink behavior on Linux
-* inotify: add `DELETE_SELF` (requested by @taralx)
-* [Fix] kqueue: handle EINTR (reported by @robfig)
-* [Doc] Godoc example [#1][] (thanks @davecheney)
-
-## v0.4.0 / 2012-03-30
-
-* Go 1 released: build with go tool
-* [Feature] Windows support using winfsnotify
-* Windows does not have attribute change notifications
-* Roll attribute notifications into IsModify
-
-## v0.3.0 / 2012-02-19
-
-* kqueue: add files when watch directory
-
-## v0.2.0 / 2011-12-30
-
-* update to latest Go weekly code
-
-## v0.1.0 / 2011-10-19
-
-* kqueue: add watch on file creation to match inotify
-* kqueue: create file event
-* inotify: ignore `IN_IGNORED` events
-* event String()
-* linux: common FileEvent functions
-* initial commit
-
-[#79]: https://github.com/howeyc/fsnotify/pull/79
-[#77]: https://github.com/howeyc/fsnotify/pull/77
-[#72]: https://github.com/howeyc/fsnotify/issues/72
-[#71]: https://github.com/howeyc/fsnotify/issues/71
-[#70]: https://github.com/howeyc/fsnotify/issues/70
-[#63]: https://github.com/howeyc/fsnotify/issues/63
-[#62]: https://github.com/howeyc/fsnotify/issues/62
-[#60]: https://github.com/howeyc/fsnotify/issues/60
-[#59]: https://github.com/howeyc/fsnotify/issues/59
-[#49]: https://github.com/howeyc/fsnotify/issues/49
-[#45]: https://github.com/howeyc/fsnotify/issues/45
-[#40]: https://github.com/howeyc/fsnotify/issues/40
-[#36]: https://github.com/howeyc/fsnotify/issues/36
-[#33]: https://github.com/howeyc/fsnotify/issues/33
-[#29]: https://github.com/howeyc/fsnotify/issues/29
-[#25]: https://github.com/howeyc/fsnotify/issues/25
-[#24]: https://github.com/howeyc/fsnotify/issues/24
-[#21]: https://github.com/howeyc/fsnotify/issues/21
-
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CONTRIBUTING.md b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CONTRIBUTING.md
deleted file mode 100644
index 0f377f341..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/CONTRIBUTING.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Contributing
-
-## Issues
-
-* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/go-fsnotify/fsnotify/issues).
-* Please indicate the platform you are using fsnotify on.
-* A code example to reproduce the problem is appreciated.
-
-## Pull Requests
-
-### Contributor License Agreement
-
-fsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/go-fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/go-fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual).
-
-Please indicate that you have signed the CLA in your pull request.
-
-### How fsnotify is Developed
-
-* Development is done on feature branches.
-* Tests are run on BSD, Linux, OS X and Windows.
-* Pull requests are reviewed and [applied to master][am] using [hub][].
- * Maintainers may modify or squash commits rather than asking contributors to.
-* To issue a new release, the maintainers will:
- * Update the CHANGELOG
- * Tag a version, which will become available through gopkg.in.
-
-### How to Fork
-
-For smooth sailing, always use the original import path. Installing with `go get` makes this easy.
-
-1. Install from GitHub (`go get -u github.com/go-fsnotify/fsnotify`)
-2. Create your feature branch (`git checkout -b my-new-feature`)
-3. Ensure everything works and the tests pass (see below)
-4. Commit your changes (`git commit -am 'Add some feature'`)
-
-Contribute upstream:
-
-1. Fork fsnotify on GitHub
-2. Add your remote (`git remote add fork git@github.com:mycompany/repo.git`)
-3. Push to the branch (`git push fork my-new-feature`)
-4. Create a new Pull Request on GitHub
-
-This workflow is [thoroughly explained by Katrina Owen](https://blog.splice.com/contributing-open-source-git-repositories-go/).
-
-### Testing
-
-fsnotify uses build tags to compile different code on Linux, BSD, OS X, and Windows.
-
-Before doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on.
-
-To aid in cross-platform testing there is a Vagrantfile for Linux and BSD.
-
-* Install [Vagrant](http://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/)
-* Setup [Vagrant Gopher](https://github.com/nathany/vagrant-gopher) in your `src` folder.
-* Run `vagrant up` from the project folder. You can also setup just one box with `vagrant up linux` or `vagrant up bsd` (note: the BSD box doesn't support Windows hosts at this time, and NFS may prompt for your host OS password)
-* Once setup, you can run the test suite on a given OS with a single command `vagrant ssh linux -c 'cd go-fsnotify/fsnotify; go test'`.
-* When you're done, you will want to halt or destroy the Vagrant boxes.
-
-Notice: fsnotify file system events won't trigger in shared folders. The tests get around this limitation by using the /tmp directory.
-
-Right now there is no equivalent solution for Windows and OS X, but there are Windows VMs [freely available from Microsoft](http://www.modern.ie/en-us/virtualization-tools#downloads).
-
-### Maintainers
-
-Help maintaining fsnotify is welcome. To be a maintainer:
-
-* Submit a pull request and sign the CLA as above.
-* You must be able to run the test suite on Mac, Windows, Linux and BSD.
-
-To keep master clean, the fsnotify project uses the "apply mail" workflow outlined in Nathaniel Talbott's post ["Merge pull request" Considered Harmful][am]. This requires installing [hub][].
-
-All code changes should be internal pull requests.
-
-Releases are tagged using [Semantic Versioning](http://semver.org/).
-
-[hub]: https://github.com/github/hub
-[am]: http://blog.spreedly.com/2014/06/24/merge-pull-request-considered-harmful/#.VGa5yZPF_Zs
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/LICENSE b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/LICENSE
deleted file mode 100644
index f21e54080..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2012 The Go Authors. All rights reserved.
-Copyright (c) 2012 fsnotify Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md
deleted file mode 100644
index f2b432e96..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# File system notifications for Go
-
-[![GoDoc](https://godoc.org/gopkg.in/fsnotify.v1?status.svg)](https://godoc.org/gopkg.in/fsnotify.v1) [![Coverage](http://gocover.io/_badge/github.com/go-fsnotify/fsnotify)](http://gocover.io/github.com/go-fsnotify/fsnotify)
-
-Go 1.3+ required.
-
-Cross platform: Windows, Linux, BSD and OS X.
-
-|Adapter |OS |Status |
-|----------|----------|----------|
-|inotify |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/go-fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/go-fsnotify/fsnotify)|
-|kqueue |BSD, OS X, iOS\*|Supported [![Build Status](https://travis-ci.org/go-fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/go-fsnotify/fsnotify)|
-|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
-|FSEvents |OS X |[Planned](https://github.com/go-fsnotify/fsnotify/issues/11)|
-|FEN |Solaris 11 |[Planned](https://github.com/go-fsnotify/fsnotify/issues/12)|
-|fanotify |Linux 2.6.37+ | |
-|USN Journals |Windows |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/53)|
-|Polling |*All* |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/9)|
-
-\* Android and iOS are untested.
-
-Please see [the documentation](https://godoc.org/gopkg.in/fsnotify.v1) for usage. Consult the [Wiki](https://github.com/go-fsnotify/fsnotify/wiki) for the FAQ and further information.
-
-## API stability
-
-Two major versions of fsnotify exist.
-
-**[fsnotify.v0](https://gopkg.in/fsnotify.v0)** is API-compatible with [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify). Bugfixes *may* be backported, but I recommend upgrading to v1.
-
-```go
-import "gopkg.in/fsnotify.v0"
-```
-
-\* Refer to the package as fsnotify (without the .v0 suffix).
-
-**[fsnotify.v1](https://gopkg.in/fsnotify.v1)** provides [a new API](https://godoc.org/gopkg.in/fsnotify.v1) based on [this design document](http://goo.gl/MrYxyA). You can import v1 with:
-
-```go
-import "gopkg.in/fsnotify.v1"
-```
-
-Further API changes are [planned](https://github.com/go-fsnotify/fsnotify/milestones), but a new major revision will be tagged, so you can depend on the v1 API.
-
-**Master** may have unreleased changes. Use it to test the very latest code or when [contributing][], but don't expect it to remain API-compatible:
-
-```go
-import "github.com/go-fsnotify/fsnotify"
-```
-
-## Contributing
-
-Please refer to [CONTRIBUTING][] before opening an issue or pull request.
-
-## Example
-
-See [example_test.go](https://github.com/go-fsnotify/fsnotify/blob/master/example_test.go).
-
-[contributing]: https://github.com/go-fsnotify/fsnotify/blob/master/CONTRIBUTING.md
-
-## Related Projects
-
-* [notify](https://github.com/rjeczalik/notify)
-* [fsevents](https://github.com/go-fsnotify/fsevents)
-
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/fsnotify.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/fsnotify.go
deleted file mode 100644
index c899ee008..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/fsnotify.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9,!solaris
-
-// Package fsnotify provides a platform-independent interface for file system notifications.
-package fsnotify
-
-import (
- "bytes"
- "fmt"
-)
-
-// Event represents a single file system notification.
-type Event struct {
- Name string // Relative path to the file or directory.
- Op Op // File operation that triggered the event.
-}
-
-// Op describes a set of file operations.
-type Op uint32
-
-// These are the generalized file operations that can trigger a notification.
-const (
- Create Op = 1 << iota
- Write
- Remove
- Rename
- Chmod
-)
-
-// String returns a string representation of the event in the form
-// "file: REMOVE|WRITE|..."
-func (e Event) String() string {
- // Use a buffer for efficient string concatenation
- var buffer bytes.Buffer
-
- if e.Op&Create == Create {
- buffer.WriteString("|CREATE")
- }
- if e.Op&Remove == Remove {
- buffer.WriteString("|REMOVE")
- }
- if e.Op&Write == Write {
- buffer.WriteString("|WRITE")
- }
- if e.Op&Rename == Rename {
- buffer.WriteString("|RENAME")
- }
- if e.Op&Chmod == Chmod {
- buffer.WriteString("|CHMOD")
- }
-
- // If buffer remains empty, return no event names
- if buffer.Len() == 0 {
- return fmt.Sprintf("%q: ", e.Name)
- }
-
- // Return a list of event names, with leading pipe character stripped
- return fmt.Sprintf("%q: %s", e.Name, buffer.String()[1:])
-}
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify.go
deleted file mode 100644
index 06f4bba88..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify.go
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-)
-
-// Watcher watches a set of files, delivering events to a channel.
-type Watcher struct {
- Events chan Event
- Errors chan error
- mu sync.Mutex // Map access
- cv *sync.Cond // sync removing on rm_watch with IN_IGNORE
- fd int
- poller *fdPoller
- watches map[string]*watch // Map of inotify watches (key: path)
- paths map[int]string // Map of watched paths (key: watch descriptor)
- done chan struct{} // Channel for sending a "quit message" to the reader goroutine
- doneResp chan struct{} // Channel to respond to Close
-}
-
-// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
-func NewWatcher() (*Watcher, error) {
- // Create inotify fd
- fd, errno := syscall.InotifyInit()
- if fd == -1 {
- return nil, errno
- }
- // Create epoll
- poller, err := newFdPoller(fd)
- if err != nil {
- syscall.Close(fd)
- return nil, err
- }
- w := &Watcher{
- fd: fd,
- poller: poller,
- watches: make(map[string]*watch),
- paths: make(map[int]string),
- Events: make(chan Event),
- Errors: make(chan error),
- done: make(chan struct{}),
- doneResp: make(chan struct{}),
- }
- w.cv = sync.NewCond(&w.mu)
-
- go w.readEvents()
- return w, nil
-}
-
-func (w *Watcher) isClosed() bool {
- select {
- case <-w.done:
- return true
- default:
- return false
- }
-}
-
-// Close removes all watches and closes the events channel.
-func (w *Watcher) Close() error {
- if w.isClosed() {
- return nil
- }
-
- // Send 'close' signal to goroutine, and set the Watcher to closed.
- close(w.done)
-
- // Wake up goroutine
- w.poller.wake()
-
- // Wait for goroutine to close
- <-w.doneResp
-
- return nil
-}
-
-// Add starts watching the named file or directory (non-recursively).
-func (w *Watcher) Add(name string) error {
- name = filepath.Clean(name)
- if w.isClosed() {
- return errors.New("inotify instance already closed")
- }
-
- const agnosticEvents = syscall.IN_MOVED_TO | syscall.IN_MOVED_FROM |
- syscall.IN_CREATE | syscall.IN_ATTRIB | syscall.IN_MODIFY |
- syscall.IN_MOVE_SELF | syscall.IN_DELETE | syscall.IN_DELETE_SELF
-
- var flags uint32 = agnosticEvents
-
- w.mu.Lock()
- watchEntry, found := w.watches[name]
- w.mu.Unlock()
- if found {
- watchEntry.flags |= flags
- flags |= syscall.IN_MASK_ADD
- }
- wd, errno := syscall.InotifyAddWatch(w.fd, name, flags)
- if wd == -1 {
- return errno
- }
-
- w.mu.Lock()
- w.watches[name] = &watch{wd: uint32(wd), flags: flags}
- w.paths[wd] = name
- w.mu.Unlock()
-
- return nil
-}
-
-// Remove stops watching the named file or directory (non-recursively).
-func (w *Watcher) Remove(name string) error {
- name = filepath.Clean(name)
-
- // Fetch the watch.
- w.mu.Lock()
- defer w.mu.Unlock()
- watch, ok := w.watches[name]
-
- // Remove it from inotify.
- if !ok {
- return fmt.Errorf("can't remove non-existent inotify watch for: %s", name)
- }
- // inotify_rm_watch will return EINVAL if the file has been deleted;
- // the inotify will already have been removed.
- // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously
- // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE
- // so that EINVAL means that the wd is being rm_watch()ed or its file removed
- // by another thread and we have not received IN_IGNORE event.
- success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
- if success == -1 {
- // TODO: Perhaps it's not helpful to return an error here in every case.
- // the only two possible errors are:
- // EBADF, which happens when w.fd is not a valid file descriptor of any kind.
- // EINVAL, which is when fd is not an inotify descriptor or wd is not a valid watch descriptor.
- // Watch descriptors are invalidated when they are removed explicitly or implicitly;
- // explicitly by inotify_rm_watch, implicitly when the file they are watching is deleted.
- return errno
- }
-
- // wait until ignoreLinux() deleting maps
- exists := true
- for exists {
- w.cv.Wait()
- _, exists = w.watches[name]
- }
-
- return nil
-}
-
-type watch struct {
- wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
- flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)
-}
-
-// readEvents reads from the inotify file descriptor, converts the
-// received events into Event objects and sends them via the Events channel
-func (w *Watcher) readEvents() {
- var (
- buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
- n int // Number of bytes read with read()
- errno error // Syscall errno
- ok bool // For poller.wait
- )
-
- defer close(w.doneResp)
- defer close(w.Errors)
- defer close(w.Events)
- defer syscall.Close(w.fd)
- defer w.poller.close()
-
- for {
- // See if we have been closed.
- if w.isClosed() {
- return
- }
-
- ok, errno = w.poller.wait()
- if errno != nil {
- select {
- case w.Errors <- errno:
- case <-w.done:
- return
- }
- continue
- }
-
- if !ok {
- continue
- }
-
- n, errno = syscall.Read(w.fd, buf[:])
- // If a signal interrupted execution, see if we've been asked to close, and try again.
- // http://man7.org/linux/man-pages/man7/signal.7.html :
- // "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable"
- if errno == syscall.EINTR {
- continue
- }
-
- // syscall.Read might have been woken up by Close. If so, we're done.
- if w.isClosed() {
- return
- }
-
- if n < syscall.SizeofInotifyEvent {
- var err error
- if n == 0 {
- // If EOF is received. This should really never happen.
- err = io.EOF
- } else if n < 0 {
- // If an error occured while reading.
- err = errno
- } else {
- // Read was too short.
- err = errors.New("notify: short read in readEvents()")
- }
- select {
- case w.Errors <- err:
- case <-w.done:
- return
- }
- continue
- }
-
- var offset uint32
- // We don't know how many events we just read into the buffer
- // While the offset points to at least one whole event...
- for offset <= uint32(n-syscall.SizeofInotifyEvent) {
- // Point "raw" to the event in the buffer
- raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
-
- mask := uint32(raw.Mask)
- nameLen := uint32(raw.Len)
- // If the event happened to the watched directory or the watched file, the kernel
- // doesn't append the filename to the event, but we would like to always fill the
- // the "Name" field with a valid filename. We retrieve the path of the watch from
- // the "paths" map.
- w.mu.Lock()
- name := w.paths[int(raw.Wd)]
- w.mu.Unlock()
- if nameLen > 0 {
- // Point "bytes" at the first byte of the filename
- bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
- // The filename is padded with NULL bytes. TrimRight() gets rid of those.
- name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
- }
-
- event := newEvent(name, mask)
-
- // Send the events that are not ignored on the events channel
- if !event.ignoreLinux(w, raw.Wd, mask) {
- select {
- case w.Events <- event:
- case <-w.done:
- return
- }
- }
-
- // Move to the next event in the buffer
- offset += syscall.SizeofInotifyEvent + nameLen
- }
- }
-}
-
-// Certain types of events can be "ignored" and not sent over the Events
-// channel. Such as events marked ignore by the kernel, or MODIFY events
-// against files that do not exist.
-func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
- // Ignore anything the inotify API says to ignore
- if mask&syscall.IN_IGNORED == syscall.IN_IGNORED {
- w.mu.Lock()
- defer w.mu.Unlock()
- name := w.paths[int(wd)]
- delete(w.paths, int(wd))
- delete(w.watches, name)
- w.cv.Broadcast()
- return true
- }
-
- // If the event is not a DELETE or RENAME, the file must exist.
- // Otherwise the event is ignored.
- // *Note*: this was put in place because it was seen that a MODIFY
- // event was sent after the DELETE. This ignores that MODIFY and
- // assumes a DELETE will come or has come if the file doesn't exist.
- if !(e.Op&Remove == Remove || e.Op&Rename == Rename) {
- _, statErr := os.Lstat(e.Name)
- return os.IsNotExist(statErr)
- }
- return false
-}
-
-// newEvent returns an platform-independent Event based on an inotify mask.
-func newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&syscall.IN_CREATE == syscall.IN_CREATE || mask&syscall.IN_MOVED_TO == syscall.IN_MOVED_TO {
- e.Op |= Create
- }
- if mask&syscall.IN_DELETE_SELF == syscall.IN_DELETE_SELF || mask&syscall.IN_DELETE == syscall.IN_DELETE {
- e.Op |= Remove
- }
- if mask&syscall.IN_MODIFY == syscall.IN_MODIFY {
- e.Op |= Write
- }
- if mask&syscall.IN_MOVE_SELF == syscall.IN_MOVE_SELF || mask&syscall.IN_MOVED_FROM == syscall.IN_MOVED_FROM {
- e.Op |= Rename
- }
- if mask&syscall.IN_ATTRIB == syscall.IN_ATTRIB {
- e.Op |= Chmod
- }
- return e
-}
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify_poller.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify_poller.go
deleted file mode 100644
index 23a5ca146..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/inotify_poller.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-package fsnotify
-
-import (
- "errors"
- "syscall"
-)
-
-type fdPoller struct {
- fd int // File descriptor (as returned by the inotify_init() syscall)
- epfd int // Epoll file descriptor
- pipe [2]int // Pipe for waking up
-}
-
-func emptyPoller(fd int) *fdPoller {
- poller := new(fdPoller)
- poller.fd = fd
- poller.epfd = -1
- poller.pipe[0] = -1
- poller.pipe[1] = -1
- return poller
-}
-
-// Create a new inotify poller.
-// This creates an inotify handler, and an epoll handler.
-func newFdPoller(fd int) (*fdPoller, error) {
- var errno error
- poller := emptyPoller(fd)
- defer func() {
- if errno != nil {
- poller.close()
- }
- }()
- poller.fd = fd
-
- // Create epoll fd
- poller.epfd, errno = syscall.EpollCreate1(0)
- if poller.epfd == -1 {
- return nil, errno
- }
- // Create pipe; pipe[0] is the read end, pipe[1] the write end.
- errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK)
- if errno != nil {
- return nil, errno
- }
-
- // Register inotify fd with epoll
- event := syscall.EpollEvent{
- Fd: int32(poller.fd),
- Events: syscall.EPOLLIN,
- }
- errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
- if errno != nil {
- return nil, errno
- }
-
- // Register pipe fd with epoll
- event = syscall.EpollEvent{
- Fd: int32(poller.pipe[0]),
- Events: syscall.EPOLLIN,
- }
- errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
- if errno != nil {
- return nil, errno
- }
-
- return poller, nil
-}
-
-// Wait using epoll.
-// Returns true if something is ready to be read,
-// false if there is not.
-func (poller *fdPoller) wait() (bool, error) {
- // 3 possible events per fd, and 2 fds, makes a maximum of 6 events.
- // I don't know whether epoll_wait returns the number of events returned,
- // or the total number of events ready.
- // I decided to catch both by making the buffer one larger than the maximum.
- events := make([]syscall.EpollEvent, 7)
- for {
- n, errno := syscall.EpollWait(poller.epfd, events, -1)
- if n == -1 {
- if errno == syscall.EINTR {
- continue
- }
- return false, errno
- }
- if n == 0 {
- // If there are no events, try again.
- continue
- }
- if n > 6 {
- // This should never happen. More events were returned than should be possible.
- return false, errors.New("epoll_wait returned more events than I know what to do with")
- }
- ready := events[:n]
- epollhup := false
- epollerr := false
- epollin := false
- for _, event := range ready {
- if event.Fd == int32(poller.fd) {
- if event.Events&syscall.EPOLLHUP != 0 {
- // This should not happen, but if it does, treat it as a wakeup.
- epollhup = true
- }
- if event.Events&syscall.EPOLLERR != 0 {
- // If an error is waiting on the file descriptor, we should pretend
- // something is ready to read, and let syscall.Read pick up the error.
- epollerr = true
- }
- if event.Events&syscall.EPOLLIN != 0 {
- // There is data to read.
- epollin = true
- }
- }
- if event.Fd == int32(poller.pipe[0]) {
- if event.Events&syscall.EPOLLHUP != 0 {
- // Write pipe descriptor was closed, by us. This means we're closing down the
- // watcher, and we should wake up.
- }
- if event.Events&syscall.EPOLLERR != 0 {
- // If an error is waiting on the pipe file descriptor.
- // This is an absolute mystery, and should never ever happen.
- return false, errors.New("Error on the pipe descriptor.")
- }
- if event.Events&syscall.EPOLLIN != 0 {
- // This is a regular wakeup, so we have to clear the buffer.
- err := poller.clearWake()
- if err != nil {
- return false, err
- }
- }
- }
- }
-
- if epollhup || epollerr || epollin {
- return true, nil
- }
- return false, nil
- }
-}
-
-// Close the write end of the poller.
-func (poller *fdPoller) wake() error {
- buf := make([]byte, 1)
- n, errno := syscall.Write(poller.pipe[1], buf)
- if n == -1 {
- if errno == syscall.EAGAIN {
- // Buffer is full, poller will wake.
- return nil
- }
- return errno
- }
- return nil
-}
-
-func (poller *fdPoller) clearWake() error {
- // You have to be woken up a LOT in order to get to 100!
- buf := make([]byte, 100)
- n, errno := syscall.Read(poller.pipe[0], buf)
- if n == -1 {
- if errno == syscall.EAGAIN {
- // Buffer is empty, someone else cleared our wake.
- return nil
- }
- return errno
- }
- return nil
-}
-
-// Close all poller file descriptors, but not the one passed to it.
-func (poller *fdPoller) close() {
- if poller.pipe[1] != -1 {
- syscall.Close(poller.pipe[1])
- }
- if poller.pipe[0] != -1 {
- syscall.Close(poller.pipe[0])
- }
- if poller.epfd != -1 {
- syscall.Close(poller.epfd)
- }
-}
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go
deleted file mode 100644
index 9662a50a8..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go
+++ /dev/null
@@ -1,481 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build freebsd openbsd netbsd dragonfly darwin
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "sync"
- "syscall"
- "time"
-)
-
-// Watcher watches a set of files, delivering events to a channel.
-type Watcher struct {
- Events chan Event
- Errors chan error
- done chan bool // Channel for sending a "quit message" to the reader goroutine
-
- kq int // File descriptor (as returned by the kqueue() syscall).
-
- mu sync.Mutex // Protects access to watcher data
- watches map[string]int // Map of watched file descriptors (key: path).
- externalWatches map[string]bool // Map of watches added by user of the library.
- dirFlags map[string]uint32 // Map of watched directories to fflags used in kqueue.
- paths map[int]pathInfo // Map file descriptors to path names for processing kqueue events.
- fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events).
- isClosed bool // Set to true when Close() is first called
-}
-
-type pathInfo struct {
- name string
- isDir bool
-}
-
-// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
-func NewWatcher() (*Watcher, error) {
- kq, err := kqueue()
- if err != nil {
- return nil, err
- }
-
- w := &Watcher{
- kq: kq,
- watches: make(map[string]int),
- dirFlags: make(map[string]uint32),
- paths: make(map[int]pathInfo),
- fileExists: make(map[string]bool),
- externalWatches: make(map[string]bool),
- Events: make(chan Event),
- Errors: make(chan error),
- done: make(chan bool),
- }
-
- go w.readEvents()
- return w, nil
-}
-
-// Close removes all watches and closes the events channel.
-func (w *Watcher) Close() error {
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
- return nil
- }
- w.isClosed = true
- w.mu.Unlock()
-
- w.mu.Lock()
- ws := w.watches
- w.mu.Unlock()
-
- var err error
- for name := range ws {
- if e := w.Remove(name); e != nil && err == nil {
- err = e
- }
- }
-
- // Send "quit" message to the reader goroutine:
- w.done <- true
-
- return nil
-}
-
-// Add starts watching the named file or directory (non-recursively).
-func (w *Watcher) Add(name string) error {
- w.mu.Lock()
- w.externalWatches[name] = true
- w.mu.Unlock()
- _, err := w.addWatch(name, noteAllEvents)
- return err
-}
-
-// Remove stops watching the the named file or directory (non-recursively).
-func (w *Watcher) Remove(name string) error {
- name = filepath.Clean(name)
- w.mu.Lock()
- watchfd, ok := w.watches[name]
- w.mu.Unlock()
- if !ok {
- return fmt.Errorf("can't remove non-existent kevent watch for: %s", name)
- }
-
- const registerRemove = syscall.EV_DELETE
- if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {
- return err
- }
-
- syscall.Close(watchfd)
-
- w.mu.Lock()
- isDir := w.paths[watchfd].isDir
- delete(w.watches, name)
- delete(w.paths, watchfd)
- delete(w.dirFlags, name)
- w.mu.Unlock()
-
- // Find all watched paths that are in this directory that are not external.
- if isDir {
- var pathsToRemove []string
- w.mu.Lock()
- for _, path := range w.paths {
- wdir, _ := filepath.Split(path.name)
- if filepath.Clean(wdir) == name {
- if !w.externalWatches[path.name] {
- pathsToRemove = append(pathsToRemove, path.name)
- }
- }
- }
- w.mu.Unlock()
- for _, name := range pathsToRemove {
- // Since these are internal, not much sense in propagating error
- // to the user, as that will just confuse them with an error about
- // a path they did not explicitly watch themselves.
- w.Remove(name)
- }
- }
-
- return nil
-}
-
-// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
-const noteAllEvents = syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_RENAME
-
-// keventWaitTime to block on each read from kevent
-var keventWaitTime = durationToTimespec(100 * time.Millisecond)
-
-// addWatch adds name to the watched file set.
-// The flags are interpreted as described in kevent(2).
-// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks.
-func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
- var isDir bool
- // Make ./name and name equivalent
- name = filepath.Clean(name)
-
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
- return "", errors.New("kevent instance already closed")
- }
- watchfd, alreadyWatching := w.watches[name]
- // We already have a watch, but we can still override flags.
- if alreadyWatching {
- isDir = w.paths[watchfd].isDir
- }
- w.mu.Unlock()
-
- if !alreadyWatching {
- fi, err := os.Lstat(name)
- if err != nil {
- return "", err
- }
-
- // Don't watch sockets.
- if fi.Mode()&os.ModeSocket == os.ModeSocket {
- return "", nil
- }
-
- // Don't watch named pipes.
- if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
- return "", nil
- }
-
- // Follow Symlinks
- // Unfortunately, Linux can add bogus symlinks to watch list without
- // issue, and Windows can't do symlinks period (AFAIK). To maintain
- // consistency, we will act like everything is fine. There will simply
- // be no file events for broken symlinks.
- // Hence the returns of nil on errors.
- if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
- name, err = filepath.EvalSymlinks(name)
- if err != nil {
- return "", nil
- }
-
- w.mu.Lock()
- _, alreadyWatching = w.watches[name]
- w.mu.Unlock()
-
- if alreadyWatching {
- return name, nil
- }
-
- fi, err = os.Lstat(name)
- if err != nil {
- return "", nil
- }
- }
-
- watchfd, err = syscall.Open(name, openMode, 0700)
- if watchfd == -1 {
- return "", err
- }
-
- isDir = fi.IsDir()
- }
-
- const registerAdd = syscall.EV_ADD | syscall.EV_CLEAR | syscall.EV_ENABLE
- if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {
- syscall.Close(watchfd)
- return "", err
- }
-
- if !alreadyWatching {
- w.mu.Lock()
- w.watches[name] = watchfd
- w.paths[watchfd] = pathInfo{name: name, isDir: isDir}
- w.mu.Unlock()
- }
-
- if isDir {
- // Watch the directory if it has not been watched before,
- // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
- w.mu.Lock()
-
- watchDir := (flags&syscall.NOTE_WRITE) == syscall.NOTE_WRITE &&
- (!alreadyWatching || (w.dirFlags[name]&syscall.NOTE_WRITE) != syscall.NOTE_WRITE)
- // Store flags so this watch can be updated later
- w.dirFlags[name] = flags
- w.mu.Unlock()
-
- if watchDir {
- if err := w.watchDirectoryFiles(name); err != nil {
- return "", err
- }
- }
- }
- return name, nil
-}
-
-// readEvents reads from kqueue and converts the received kevents into
-// Event values that it sends down the Events channel.
-func (w *Watcher) readEvents() {
- eventBuffer := make([]syscall.Kevent_t, 10)
-
- for {
- // See if there is a message on the "done" channel
- select {
- case <-w.done:
- err := syscall.Close(w.kq)
- if err != nil {
- w.Errors <- err
- }
- close(w.Events)
- close(w.Errors)
- return
- default:
- }
-
- // Get new events
- kevents, err := read(w.kq, eventBuffer, &keventWaitTime)
- // EINTR is okay, the syscall was interrupted before timeout expired.
- if err != nil && err != syscall.EINTR {
- w.Errors <- err
- continue
- }
-
- // Flush the events we received to the Events channel
- for len(kevents) > 0 {
- kevent := &kevents[0]
- watchfd := int(kevent.Ident)
- mask := uint32(kevent.Fflags)
- w.mu.Lock()
- path := w.paths[watchfd]
- w.mu.Unlock()
- event := newEvent(path.name, mask)
-
- if path.isDir && !(event.Op&Remove == Remove) {
- // Double check to make sure the directory exists. This can happen when
- // we do a rm -fr on a recursively watched folders and we receive a
- // modification event first but the folder has been deleted and later
- // receive the delete event
- if _, err := os.Lstat(event.Name); os.IsNotExist(err) {
- // mark is as delete event
- event.Op |= Remove
- }
- }
-
- if event.Op&Rename == Rename || event.Op&Remove == Remove {
- w.Remove(event.Name)
- w.mu.Lock()
- delete(w.fileExists, event.Name)
- w.mu.Unlock()
- }
-
- if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) {
- w.sendDirectoryChangeEvents(event.Name)
- } else {
- // Send the event on the Events channel
- w.Events <- event
- }
-
- if event.Op&Remove == Remove {
- // Look for a file that may have overwritten this.
- // For example, mv f1 f2 will delete f2, then create f2.
- fileDir, _ := filepath.Split(event.Name)
- fileDir = filepath.Clean(fileDir)
- w.mu.Lock()
- _, found := w.watches[fileDir]
- w.mu.Unlock()
- if found {
- // make sure the directory exists before we watch for changes. When we
- // do a recursive watch and perform rm -fr, the parent directory might
- // have gone missing, ignore the missing directory and let the
- // upcoming delete event remove the watch from the parent directory.
- if _, err := os.Lstat(fileDir); os.IsExist(err) {
- w.sendDirectoryChangeEvents(fileDir)
- // FIXME: should this be for events on files or just isDir?
- }
- }
- }
-
- // Move to next event
- kevents = kevents[1:]
- }
- }
-}
-
-// newEvent returns an platform-independent Event based on kqueue Fflags.
-func newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&syscall.NOTE_DELETE == syscall.NOTE_DELETE {
- e.Op |= Remove
- }
- if mask&syscall.NOTE_WRITE == syscall.NOTE_WRITE {
- e.Op |= Write
- }
- if mask&syscall.NOTE_RENAME == syscall.NOTE_RENAME {
- e.Op |= Rename
- }
- if mask&syscall.NOTE_ATTRIB == syscall.NOTE_ATTRIB {
- e.Op |= Chmod
- }
- return e
-}
-
-func newCreateEvent(name string) Event {
- return Event{Name: name, Op: Create}
-}
-
-// watchDirectoryFiles to mimic inotify when adding a watch on a directory
-func (w *Watcher) watchDirectoryFiles(dirPath string) error {
- // Get all files
- files, err := ioutil.ReadDir(dirPath)
- if err != nil {
- return err
- }
-
- for _, fileInfo := range files {
- filePath := filepath.Join(dirPath, fileInfo.Name())
- filePath, err = w.internalWatch(filePath, fileInfo)
- if err != nil {
- return err
- }
-
- w.mu.Lock()
- w.fileExists[filePath] = true
- w.mu.Unlock()
- }
-
- return nil
-}
-
-// sendDirectoryEvents searches the directory for newly created files
-// and sends them over the event channel. This functionality is to have
-// the BSD version of fsnotify match Linux inotify which provides a
-// create event for files created in a watched directory.
-func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
- // Get all files
- files, err := ioutil.ReadDir(dirPath)
- if err != nil {
- w.Errors <- err
- }
-
- // Search for new files
- for _, fileInfo := range files {
- filePath := filepath.Join(dirPath, fileInfo.Name())
- w.mu.Lock()
- _, doesExist := w.fileExists[filePath]
- w.mu.Unlock()
- if !doesExist {
- // Send create event
- w.Events <- newCreateEvent(filePath)
- }
-
- // like watchDirectoryFiles (but without doing another ReadDir)
- filePath, err = w.internalWatch(filePath, fileInfo)
- if err != nil {
- return
- }
-
- w.mu.Lock()
- w.fileExists[filePath] = true
- w.mu.Unlock()
- }
-}
-
-func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) {
- if fileInfo.IsDir() {
- // mimic Linux providing delete events for subdirectories
- // but preserve the flags used if currently watching subdirectory
- w.mu.Lock()
- flags := w.dirFlags[name]
- w.mu.Unlock()
-
- flags |= syscall.NOTE_DELETE | syscall.NOTE_RENAME
- return w.addWatch(name, flags)
- }
-
- // watch file to mimic Linux inotify
- return w.addWatch(name, noteAllEvents)
-}
-
-// kqueue creates a new kernel event queue and returns a descriptor.
-func kqueue() (kq int, err error) {
- kq, err = syscall.Kqueue()
- if kq == -1 {
- return kq, err
- }
- return kq, nil
-}
-
-// register events with the queue
-func register(kq int, fds []int, flags int, fflags uint32) error {
- changes := make([]syscall.Kevent_t, len(fds))
-
- for i, fd := range fds {
- // SetKevent converts int to the platform-specific types:
- syscall.SetKevent(&changes[i], fd, syscall.EVFILT_VNODE, flags)
- changes[i].Fflags = fflags
- }
-
- // register the events
- success, err := syscall.Kevent(kq, changes, nil, nil)
- if success == -1 {
- return err
- }
- return nil
-}
-
-// read retrieves pending events, or waits until an event occurs.
-// A timeout of nil blocks indefinitely, while 0 polls the queue.
-func read(kq int, events []syscall.Kevent_t, timeout *syscall.Timespec) ([]syscall.Kevent_t, error) {
- n, err := syscall.Kevent(kq, nil, events, timeout)
- if err != nil {
- return nil, err
- }
- return events[0:n], nil
-}
-
-// durationToTimespec prepares a timeout value
-func durationToTimespec(d time.Duration) syscall.Timespec {
- return syscall.NsecToTimespec(d.Nanoseconds())
-}
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_bsd.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_bsd.go
deleted file mode 100644
index c57ccb427..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_bsd.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build freebsd openbsd netbsd dragonfly
-
-package fsnotify
-
-import "syscall"
-
-const openMode = syscall.O_NONBLOCK | syscall.O_RDONLY
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_darwin.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_darwin.go
deleted file mode 100644
index 174b2c331..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_darwin.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin
-
-package fsnotify
-
-import "syscall"
-
-// note: this constant is not defined on BSD
-const openMode = syscall.O_EVTONLY
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/windows.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/windows.go
deleted file mode 100644
index 811585227..000000000
--- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/windows.go
+++ /dev/null
@@ -1,561 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "sync"
- "syscall"
- "unsafe"
-)
-
-// Watcher watches a set of files, delivering events to a channel.
-type Watcher struct {
- Events chan Event
- Errors chan error
- isClosed bool // Set to true when Close() is first called
- mu sync.Mutex // Map access
- port syscall.Handle // Handle to completion port
- watches watchMap // Map of watches (key: i-number)
- input chan *input // Inputs to the reader are sent on this channel
- quit chan chan<- error
-}
-
-// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
-func NewWatcher() (*Watcher, error) {
- port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0)
- if e != nil {
- return nil, os.NewSyscallError("CreateIoCompletionPort", e)
- }
- w := &Watcher{
- port: port,
- watches: make(watchMap),
- input: make(chan *input, 1),
- Events: make(chan Event, 50),
- Errors: make(chan error),
- quit: make(chan chan<- error, 1),
- }
- go w.readEvents()
- return w, nil
-}
-
-// Close removes all watches and closes the events channel.
-func (w *Watcher) Close() error {
- if w.isClosed {
- return nil
- }
- w.isClosed = true
-
- // Send "quit" message to the reader goroutine
- ch := make(chan error)
- w.quit <- ch
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-ch
-}
-
-// Add starts watching the named file or directory (non-recursively).
-func (w *Watcher) Add(name string) error {
- if w.isClosed {
- return errors.New("watcher already closed")
- }
- in := &input{
- op: opAddWatch,
- path: filepath.Clean(name),
- flags: sys_FS_ALL_EVENTS,
- reply: make(chan error),
- }
- w.input <- in
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-in.reply
-}
-
-// Remove stops watching the the named file or directory (non-recursively).
-func (w *Watcher) Remove(name string) error {
- in := &input{
- op: opRemoveWatch,
- path: filepath.Clean(name),
- reply: make(chan error),
- }
- w.input <- in
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-in.reply
-}
-
-const (
- // Options for AddWatch
- sys_FS_ONESHOT = 0x80000000
- sys_FS_ONLYDIR = 0x1000000
-
- // Events
- sys_FS_ACCESS = 0x1
- sys_FS_ALL_EVENTS = 0xfff
- sys_FS_ATTRIB = 0x4
- sys_FS_CLOSE = 0x18
- sys_FS_CREATE = 0x100
- sys_FS_DELETE = 0x200
- sys_FS_DELETE_SELF = 0x400
- sys_FS_MODIFY = 0x2
- sys_FS_MOVE = 0xc0
- sys_FS_MOVED_FROM = 0x40
- sys_FS_MOVED_TO = 0x80
- sys_FS_MOVE_SELF = 0x800
-
- // Special events
- sys_FS_IGNORED = 0x8000
- sys_FS_Q_OVERFLOW = 0x4000
-)
-
-func newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&sys_FS_CREATE == sys_FS_CREATE || mask&sys_FS_MOVED_TO == sys_FS_MOVED_TO {
- e.Op |= Create
- }
- if mask&sys_FS_DELETE == sys_FS_DELETE || mask&sys_FS_DELETE_SELF == sys_FS_DELETE_SELF {
- e.Op |= Remove
- }
- if mask&sys_FS_MODIFY == sys_FS_MODIFY {
- e.Op |= Write
- }
- if mask&sys_FS_MOVE == sys_FS_MOVE || mask&sys_FS_MOVE_SELF == sys_FS_MOVE_SELF || mask&sys_FS_MOVED_FROM == sys_FS_MOVED_FROM {
- e.Op |= Rename
- }
- if mask&sys_FS_ATTRIB == sys_FS_ATTRIB {
- e.Op |= Chmod
- }
- return e
-}
-
-const (
- opAddWatch = iota
- opRemoveWatch
-)
-
-const (
- provisional uint64 = 1 << (32 + iota)
-)
-
-type input struct {
- op int
- path string
- flags uint32
- reply chan error
-}
-
-type inode struct {
- handle syscall.Handle
- volume uint32
- index uint64
-}
-
-type watch struct {
- ov syscall.Overlapped
- ino *inode // i-number
- path string // Directory path
- mask uint64 // Directory itself is being watched with these notify flags
- names map[string]uint64 // Map of names being watched and their notify flags
- rename string // Remembers the old name while renaming a file
- buf [4096]byte
-}
-
-type indexMap map[uint64]*watch
-type watchMap map[uint32]indexMap
-
-func (w *Watcher) wakeupReader() error {
- e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil)
- if e != nil {
- return os.NewSyscallError("PostQueuedCompletionStatus", e)
- }
- return nil
-}
-
-func getDir(pathname string) (dir string, err error) {
- attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname))
- if e != nil {
- return "", os.NewSyscallError("GetFileAttributes", e)
- }
- if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- dir = pathname
- } else {
- dir, _ = filepath.Split(pathname)
- dir = filepath.Clean(dir)
- }
- return
-}
-
-func getIno(path string) (ino *inode, err error) {
- h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(path),
- syscall.FILE_LIST_DIRECTORY,
- syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
- nil, syscall.OPEN_EXISTING,
- syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)
- if e != nil {
- return nil, os.NewSyscallError("CreateFile", e)
- }
- var fi syscall.ByHandleFileInformation
- if e = syscall.GetFileInformationByHandle(h, &fi); e != nil {
- syscall.CloseHandle(h)
- return nil, os.NewSyscallError("GetFileInformationByHandle", e)
- }
- ino = &inode{
- handle: h,
- volume: fi.VolumeSerialNumber,
- index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),
- }
- return ino, nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) get(ino *inode) *watch {
- if i := m[ino.volume]; i != nil {
- return i[ino.index]
- }
- return nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) set(ino *inode, watch *watch) {
- i := m[ino.volume]
- if i == nil {
- i = make(indexMap)
- m[ino.volume] = i
- }
- i[ino.index] = watch
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) addWatch(pathname string, flags uint64) error {
- dir, err := getDir(pathname)
- if err != nil {
- return err
- }
- if flags&sys_FS_ONLYDIR != 0 && pathname != dir {
- return nil
- }
- ino, err := getIno(dir)
- if err != nil {
- return err
- }
- w.mu.Lock()
- watchEntry := w.watches.get(ino)
- w.mu.Unlock()
- if watchEntry == nil {
- if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {
- syscall.CloseHandle(ino.handle)
- return os.NewSyscallError("CreateIoCompletionPort", e)
- }
- watchEntry = &watch{
- ino: ino,
- path: dir,
- names: make(map[string]uint64),
- }
- w.mu.Lock()
- w.watches.set(ino, watchEntry)
- w.mu.Unlock()
- flags |= provisional
- } else {
- syscall.CloseHandle(ino.handle)
- }
- if pathname == dir {
- watchEntry.mask |= flags
- } else {
- watchEntry.names[filepath.Base(pathname)] |= flags
- }
- if err = w.startRead(watchEntry); err != nil {
- return err
- }
- if pathname == dir {
- watchEntry.mask &= ^provisional
- } else {
- watchEntry.names[filepath.Base(pathname)] &= ^provisional
- }
- return nil
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) remWatch(pathname string) error {
- dir, err := getDir(pathname)
- if err != nil {
- return err
- }
- ino, err := getIno(dir)
- if err != nil {
- return err
- }
- w.mu.Lock()
- watch := w.watches.get(ino)
- w.mu.Unlock()
- if watch == nil {
- return fmt.Errorf("can't remove non-existent watch for: %s", pathname)
- }
- if pathname == dir {
- w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED)
- watch.mask = 0
- } else {
- name := filepath.Base(pathname)
- w.sendEvent(watch.path+"\\"+name, watch.names[name]&sys_FS_IGNORED)
- delete(watch.names, name)
- }
- return w.startRead(watch)
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) deleteWatch(watch *watch) {
- for name, mask := range watch.names {
- if mask&provisional == 0 {
- w.sendEvent(watch.path+"\\"+name, mask&sys_FS_IGNORED)
- }
- delete(watch.names, name)
- }
- if watch.mask != 0 {
- if watch.mask&provisional == 0 {
- w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED)
- }
- watch.mask = 0
- }
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) startRead(watch *watch) error {
- if e := syscall.CancelIo(watch.ino.handle); e != nil {
- w.Errors <- os.NewSyscallError("CancelIo", e)
- w.deleteWatch(watch)
- }
- mask := toWindowsFlags(watch.mask)
- for _, m := range watch.names {
- mask |= toWindowsFlags(m)
- }
- if mask == 0 {
- if e := syscall.CloseHandle(watch.ino.handle); e != nil {
- w.Errors <- os.NewSyscallError("CloseHandle", e)
- }
- w.mu.Lock()
- delete(w.watches[watch.ino.volume], watch.ino.index)
- w.mu.Unlock()
- return nil
- }
- e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],
- uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0)
- if e != nil {
- err := os.NewSyscallError("ReadDirectoryChanges", e)
- if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
- // Watched directory was probably removed
- if w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF) {
- if watch.mask&sys_FS_ONESHOT != 0 {
- watch.mask = 0
- }
- }
- err = nil
- }
- w.deleteWatch(watch)
- w.startRead(watch)
- return err
- }
- return nil
-}
-
-// readEvents reads from the I/O completion port, converts the
-// received events into Event objects and sends them via the Events channel.
-// Entry point to the I/O thread.
-func (w *Watcher) readEvents() {
- var (
- n, key uint32
- ov *syscall.Overlapped
- )
- runtime.LockOSThread()
-
- for {
- e := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE)
- watch := (*watch)(unsafe.Pointer(ov))
-
- if watch == nil {
- select {
- case ch := <-w.quit:
- w.mu.Lock()
- var indexes []indexMap
- for _, index := range w.watches {
- indexes = append(indexes, index)
- }
- w.mu.Unlock()
- for _, index := range indexes {
- for _, watch := range index {
- w.deleteWatch(watch)
- w.startRead(watch)
- }
- }
- var err error
- if e := syscall.CloseHandle(w.port); e != nil {
- err = os.NewSyscallError("CloseHandle", e)
- }
- close(w.Events)
- close(w.Errors)
- ch <- err
- return
- case in := <-w.input:
- switch in.op {
- case opAddWatch:
- in.reply <- w.addWatch(in.path, uint64(in.flags))
- case opRemoveWatch:
- in.reply <- w.remWatch(in.path)
- }
- default:
- }
- continue
- }
-
- switch e {
- case syscall.ERROR_MORE_DATA:
- if watch == nil {
- w.Errors <- errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer")
- } else {
- // The i/o succeeded but the buffer is full.
- // In theory we should be building up a full packet.
- // In practice we can get away with just carrying on.
- n = uint32(unsafe.Sizeof(watch.buf))
- }
- case syscall.ERROR_ACCESS_DENIED:
- // Watched directory was probably removed
- w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF)
- w.deleteWatch(watch)
- w.startRead(watch)
- continue
- case syscall.ERROR_OPERATION_ABORTED:
- // CancelIo was called on this handle
- continue
- default:
- w.Errors <- os.NewSyscallError("GetQueuedCompletionPort", e)
- continue
- case nil:
- }
-
- var offset uint32
- for {
- if n == 0 {
- w.Events <- newEvent("", sys_FS_Q_OVERFLOW)
- w.Errors <- errors.New("short read in readEvents()")
- break
- }
-
- // Point "raw" to the event in the buffer
- raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
- buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName))
- name := syscall.UTF16ToString(buf[:raw.FileNameLength/2])
- fullname := watch.path + "\\" + name
-
- var mask uint64
- switch raw.Action {
- case syscall.FILE_ACTION_REMOVED:
- mask = sys_FS_DELETE_SELF
- case syscall.FILE_ACTION_MODIFIED:
- mask = sys_FS_MODIFY
- case syscall.FILE_ACTION_RENAMED_OLD_NAME:
- watch.rename = name
- case syscall.FILE_ACTION_RENAMED_NEW_NAME:
- if watch.names[watch.rename] != 0 {
- watch.names[name] |= watch.names[watch.rename]
- delete(watch.names, watch.rename)
- mask = sys_FS_MOVE_SELF
- }
- }
-
- sendNameEvent := func() {
- if w.sendEvent(fullname, watch.names[name]&mask) {
- if watch.names[name]&sys_FS_ONESHOT != 0 {
- delete(watch.names, name)
- }
- }
- }
- if raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME {
- sendNameEvent()
- }
- if raw.Action == syscall.FILE_ACTION_REMOVED {
- w.sendEvent(fullname, watch.names[name]&sys_FS_IGNORED)
- delete(watch.names, name)
- }
- if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) {
- if watch.mask&sys_FS_ONESHOT != 0 {
- watch.mask = 0
- }
- }
- if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME {
- fullname = watch.path + "\\" + watch.rename
- sendNameEvent()
- }
-
- // Move to the next event in the buffer
- if raw.NextEntryOffset == 0 {
- break
- }
- offset += raw.NextEntryOffset
-
- // Error!
- if offset >= n {
- w.Errors <- errors.New("Windows system assumed buffer larger than it is, events have likely been missed.")
- break
- }
- }
-
- if err := w.startRead(watch); err != nil {
- w.Errors <- err
- }
- }
-}
-
-func (w *Watcher) sendEvent(name string, mask uint64) bool {
- if mask == 0 {
- return false
- }
- event := newEvent(name, uint32(mask))
- select {
- case ch := <-w.quit:
- w.quit <- ch
- case w.Events <- event:
- }
- return true
-}
-
-func toWindowsFlags(mask uint64) uint32 {
- var m uint32
- if mask&sys_FS_ACCESS != 0 {
- m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS
- }
- if mask&sys_FS_MODIFY != 0 {
- m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE
- }
- if mask&sys_FS_ATTRIB != 0 {
- m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES
- }
- if mask&(sys_FS_MOVE|sys_FS_CREATE|sys_FS_DELETE) != 0 {
- m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME
- }
- return m
-}
-
-func toFSnotifyFlags(action uint32) uint64 {
- switch action {
- case syscall.FILE_ACTION_ADDED:
- return sys_FS_CREATE
- case syscall.FILE_ACTION_REMOVED:
- return sys_FS_DELETE
- case syscall.FILE_ACTION_MODIFIED:
- return sys_FS_MODIFY
- case syscall.FILE_ACTION_RENAMED_OLD_NAME:
- return sys_FS_MOVED_FROM
- case syscall.FILE_ACTION_RENAMED_NEW_NAME:
- return sys_FS_MOVED_TO
- }
- return 0
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.gitignore b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.gitignore
deleted file mode 100644
index c2a6499b4..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.DS_Store
-*.swp
-*.swo
-*.test
-examples/interval/interval
-examples/interval-vary/interval-vary
-examples/interval-many/interval-many
-examples/memstats/memstats
-examples/rate-limit/rate-limit
-examples/custom/custom
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.travis.yml b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.travis.yml
deleted file mode 100644
index 1b2427202..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-sudo: false
-language: go
-
-go:
- - 1.2
- - tip
-
-install: go get -t ./...
-
-script: go test -v -short ./...
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/LICENSE b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/LICENSE
deleted file mode 100644
index f9616483e..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/LICENSE
+++ /dev/null
@@ -1,12 +0,0 @@
-Copyright (c) 2014, Martin Angers and Contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
-* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/README.md b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/README.md
deleted file mode 100644
index fbb4a01fc..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/README.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Throttled [![build status](https://secure.travis-ci.org/throttled/throttled.png)](http://travis-ci.org/throttled/throttled) [![GoDoc](https://godoc.org/gopkg.in/throttled/throttled.v1?status.png)](http://godoc.org/gopkg.in/throttled/throttled.v1)
-
-Package throttled implements different throttling strategies for controlling
-access to HTTP handlers.
-
-*As of July 27, 2015, the package is now located under its own GitHub
- organization and uses gopkg.in for versioning, please adjust your
- imports to `gopkg.in/throttled/throttled.v1`.*
-
-## Installation
-
-`go get gopkg.in/throttled/throttled.v1/...`
-
-## Interval
-
-The Interval function creates a throttler that allows requests to go through at
-a controlled, constant interval. The interval may be applied to all requests
-(vary argument == nil) or independently based on vary-by criteria.
-
-For example:
-
- th := throttled.Interval(throttled.PerSec(10), 100, &throttled.VaryBy{Path: true}, 50)
- h := th.Throttle(myHandler)
- http.ListenAndServe(":9000", h)
-
-Creates a throttler that will allow a request each 100ms (10 requests per second), with
-a buffer of 100 exceeding requests before dropping requests with a status code 429 (by
-default, configurable using th.DeniedHandler or the package-global DefaultDeniedHandler
-variable). Different paths will be throttled independently, so that /path_a and /path_b
-both can serve 10 requests per second. The last argument, 50, indicates the maximum number
-of keys that the throttler will keep in memory.
-
-## MemStats
-
-The MemStats function creates a throttler that allows requests to go through only if
-the memory statistics of the current process are below specified thresholds.
-
-For example:
-
- th := throttled.MemStats(throttled.MemThresholds(&runtime.MemStats{NumGC: 10}, 10*time.Millisecond)
- h := th.Throttle(myHandler)
- http.ListenAndServe(":9000", h)
-
-Creates a throttler that will allow requests to go through until the number of garbage
-collections reaches the initial number + 10 (the MemThresholds function creates absolute
-memory stats thresholds from offsets). The second argument, 10ms, indicates the refresh
-rate of the memory stats.
-
-## RateLimit
-
-The RateLimit function creates a throttler that allows a certain number of requests in
-a given time window, as is often implemented in public RESTful APIs.
-
-For example:
-
- th := throttled.RateLimit(throttled.PerMin(30), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(1000))
- h := th.Throttle(myHandler)
- http.ListenAndServe(":9000", h)
-
-Creates a throttler that will limit requests to 30 per minute, based on the remote address
-of the client, and will store the counter and remaining time of the current window in the
-provided memory store, limiting the number of keys to keep in memory to 1000. The store
-sub-package also provides a Redis-based Store implementations.
-
-The RateLimit throttler sets the expected X-RateLimit-* headers on the response, and
-also sets a Retry-After header when the limit is exceeded.
-
-## Documentation
-
-The API documentation is available as usual on [godoc.org][doc].
-
-There is also a [blog post explaining the package's usage on 0value.com][blog].
-
-Finally, many examples are provided in the /examples sub-folder of the repository.
-
-## License
-
-The [BSD 3-clause license][bsd]. Copyright (c) 2014 Martin Angers and Contributors.
-
-[doc]: http://godoc.org/gopkg.in/throttled/throttled.v1
-[blog]: http://0value.com/throttled--guardian-of-the-web-server
-[bsd]: http://opensource.org/licenses/BSD-3-Clause
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/delayer.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/delayer.go
deleted file mode 100644
index e62ec9e86..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/delayer.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package throttled
-
-import "time"
-
-// The Quota interface defines the method to implement to describe
-// a time-window quota, as required by the RateLimit throttler.
-type Quota interface {
- // Quota returns a number of requests allowed, and a duration.
- Quota() (int, time.Duration)
-}
-
-// The Delayer interface defines the method to implement to describe
-// a delay as required by the Interval throttler.
-type Delayer interface {
- // Delay returns a duration.
- Delay() time.Duration
-}
-
-// PerSec represents a number of requests per second.
-type PerSec int
-
-// Delay returns the duration to wait before the next request can go through,
-// so that PerSec(n) == n requests per second at regular intervals.
-func (ps PerSec) Delay() time.Duration {
- if ps <= 0 {
- return 0
- }
- return time.Duration(1.0 / float64(ps) * float64(time.Second))
-}
-
-// Quota returns the number of requests allowed in a 1 second time window,
-// so that PerSec(n) == n requests allowed per second.
-func (ps PerSec) Quota() (int, time.Duration) {
- return int(ps), time.Second
-}
-
-// PerMin represents a number of requests per minute.
-type PerMin int
-
-// Delay returns the duration to wait before the next request can go through,
-// so that PerMin(n) == n requests per minute at regular intervals.
-func (pm PerMin) Delay() time.Duration {
- if pm <= 0 {
- return 0
- }
- return time.Duration(1.0 / float64(pm) * float64(time.Minute))
-}
-
-// Quota returns the number of requests allowed in a 1 minute time window,
-// so that PerMin(n) == n requests allowed per minute.
-func (pm PerMin) Quota() (int, time.Duration) {
- return int(pm), time.Minute
-}
-
-// PerHour represents a number of requests per hour.
-type PerHour int
-
-// Delay returns the duration to wait before the next request can go through,
-// so that PerHour(n) == n requests per hour at regular intervals.
-func (ph PerHour) Delay() time.Duration {
- if ph <= 0 {
- return 0
- }
- return time.Duration(1.0 / float64(ph) * float64(time.Hour))
-}
-
-// Quota returns the number of requests allowed in a 1 hour time window,
-// so that PerHour(n) == n requests allowed per hour.
-func (ph PerHour) Quota() (int, time.Duration) {
- return int(ph), time.Hour
-}
-
-// PerDay represents a number of requests per day.
-type PerDay int
-
-// Delay returns the duration to wait before the next request can go through,
-// so that PerDay(n) == n requests per day at regular intervals.
-func (pd PerDay) Delay() time.Duration {
- if pd <= 0 {
- return 0
- }
- return time.Duration(1.0 / float64(pd) * float64(24*time.Hour))
-}
-
-// Quota returns the number of requests allowed in a 1 day time window,
-// so that PerDay(n) == n requests allowed per day.
-func (pd PerDay) Quota() (int, time.Duration) {
- return int(pd), 24 * time.Hour
-}
-
-// D represents a custom delay.
-type D time.Duration
-
-// Delay returns the duration to wait before the next request can go through,
-// which is the custom duration represented by the D value.
-func (d D) Delay() time.Duration {
- return time.Duration(d)
-}
-
-// Q represents a custom quota.
-type Q struct {
- Requests int
- Window time.Duration
-}
-
-// Quota returns the number of requests allowed and the custom time window.
-func (q Q) Quota() (int, time.Duration) {
- return q.Requests, q.Window
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/doc.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/doc.go
deleted file mode 100644
index acf5213b0..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/doc.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Package throttled implements different throttling strategies for controlling
-// access to HTTP handlers.
-//
-// Installation
-//
-// go get gopkg.in/throttled/throttled.v1/...
-//
-// Inverval
-//
-// The Interval function creates a throttler that allows requests to go through at
-// a controlled, constant interval. The interval may be applied to all requests
-// (vary argument == nil) or independently based on vary-by criteria.
-//
-// For example:
-//
-// th := throttled.Interval(throttled.PerSec(10), 100, &throttled.VaryBy{Path: true}, 50)
-// h := th.Throttle(myHandler)
-// http.ListenAndServe(":9000", h)
-//
-// Creates a throttler that will allow a request each 100ms (10 requests per second), with
-// a buffer of 100 exceeding requests before dropping requests with a status code 429 (by
-// default, configurable using th.DeniedHandler or the package-global DefaultDeniedHandler
-// variable). Different paths will be throttled independently, so that /path_a and /path_b
-// both can serve 10 requests per second. The last argument, 50, indicates the maximum number
-// of keys that the throttler will keep in memory.
-//
-// MemStats
-//
-// The MemStats function creates a throttler that allows requests to go through only if
-// the memory statistics of the current process are below specified thresholds.
-//
-// For example:
-//
-// th := throttled.MemStats(throttled.MemThresholds(&runtime.MemStats{NumGC: 10}, 10*time.Millisecond)
-// h := th.Throttle(myHandler)
-// http.ListenAndServe(":9000", h)
-//
-// Creates a throttler that will allow requests to go through until the number of garbage
-// collections reaches the initial number + 10 (the MemThresholds function creates absolute
-// memory stats thresholds from offsets). The second argument, 10ms, indicates the refresh
-// rate of the memory stats.
-//
-// RateLimit
-//
-// The RateLimit function creates a throttler that allows a certain number of requests in
-// a given time window, as is often implemented in public RESTful APIs.
-//
-// For example:
-//
-// th := throttled.RateLimit(throttled.PerMin(30), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(1000))
-// h := th.Throttle(myHandler)
-// http.ListenAndServe(":9000", h)
-//
-// Creates a throttler that will limit requests to 30 per minute, based on the remote address
-// of the client, and will store the counter and remaining time of the current window in the
-// provided memory store, limiting the number of keys to keep in memory to 1000. The store
-// sub-package also provides a Redis-based Store implementations.
-//
-// The RateLimit throttler sets the expected X-RateLimit-* headers on the response, and
-// also sets a Retry-After header when the limit is exceeded.
-//
-// Documentation
-//
-// The API documentation is available as usual on godoc.org:
-// http://godoc.org/gopkg.in/throttled/throttled.v1
-//
-// There is also a blog post explaining the package's usage on 0value.com:
-// http://0value.com/throttled--guardian-of-the-web-server
-//
-// Finally, many examples are provided in the /examples sub-folder of the repository.
-//
-// License
-//
-// The BSD 3-clause license. Copyright (c) 2014 Martin Angers and Contributors.
-// http://opensource.org/licenses/BSD-3-Clause
-//
-package throttled
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/README.md b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/README.md
deleted file mode 100644
index 6b12dad20..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Examples
-
-This directory contains examples for all the throttlers implemented by the throttled package, as well as an example of a custom limiter.
-
-* custom/ : implements a custom limiter that allows requests to path /a on even seconds, and on path /b on odd seconds.
-* interval-many/ : implements a common interval throttler to control two different handlers, one for path /a and another for path /b, so that requests to any one of the handlers go through at the specified interval.
-* interval-vary/ : implements an interval throttler that varies by path, so that requests to each different path goes through at the specified interval.
-* interval/ : implements an interval throttler so that any request goes through at the specified interval, regardless of path or any other criteria.
-* memstats/ : implements a memory-usage throttler that limits access based on current memory statistics.
-* rate-limit/ : implements a rate-limiter throttler that varies by path, so that the number of requests allowed are counted based on the requested path.
-
-Each example app supports a number of command-line flags. Run the example with the -h flag to display usage and defaults.
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/custom/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/custom/main.go
deleted file mode 100644
index b3fe993e8..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/custom/main.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/http"
- "sync"
- "time"
-
- "gopkg.in/throttled/throttled.v1"
-)
-
-var (
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-// Custom limiter: allow requests to the /a path on even seconds only, and
-// allow access to the /b path on odd seconds only.
-//
-// Yes this is absurd. A more realistic case could be to allow requests to some
-// contest page only during a limited time window.
-type customLimiter struct {
-}
-
-func (c *customLimiter) Start() {
- // No-op
-}
-
-func (c *customLimiter) Limit(w http.ResponseWriter, r *http.Request) (<-chan bool, error) {
- s := time.Now().Second()
- ch := make(chan bool, 1)
- ok := (r.URL.Path == "/a" && s%2 == 0) || (r.URL.Path == "/b" && s%2 != 0)
- ch <- ok
- if *output == "v" {
- log.Printf("Custom Limiter: Path=%s, Second=%d; ok? %v", r.URL.Path, s, ok)
- }
- return ch, nil
-}
-
-func main() {
- flag.Parse()
-
- var h http.Handler
- var ok, ko int
- var mu sync.Mutex
-
- // Keep the start time to print since-time
- start := time.Now()
- // Create the custom throttler using our custom limiter
- t := throttled.Custom(&customLimiter{})
- // Set its denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("KO: %s", time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
- // Throttle the OK handler
- rand.Seed(time.Now().Unix())
- h = t.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("ok: %s", time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- w.WriteHeader(200)
- mu.Lock()
- defer mu.Unlock()
- ok++
- }))
-
- // Print stats once in a while
- go func() {
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- log.Printf("ok: %d, ko: %d", ok, ko)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", h)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-many/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-many/main.go
deleted file mode 100644
index 51a4ca023..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-many/main.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/http"
- "sync"
- "time"
-
- "gopkg.in/throttled/throttled.v1"
-)
-
-var (
- delay = flag.Duration("delay", 200*time.Millisecond, "delay between calls")
- bursts = flag.Int("bursts", 10, "number of bursts allowed")
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-func main() {
- flag.Parse()
-
- var ok, ko int
- var mu sync.Mutex
-
- // Keep start time to log since-time
- start := time.Now()
-
- // Create the interval throttle
- t := throttled.Interval(throttled.D(*delay), *bursts, nil, 0)
- // Set its denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("%s: KO: %s", r.URL.Path, time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
- // Create OK handlers
- rand.Seed(time.Now().Unix())
- makeHandler := func(ix int) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("handler %d: %s: ok: %s", ix, r.URL.Path, time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- w.WriteHeader(200)
- mu.Lock()
- defer mu.Unlock()
- ok++
- })
- }
- // Throttle them using the same interval throttler
- h1 := t.Throttle(makeHandler(1))
- h2 := t.Throttle(makeHandler(2))
-
- // Handle two paths
- mux := http.NewServeMux()
- mux.Handle("/a", h1)
- mux.Handle("/b", h2)
-
- // Print stats once in a while
- go func() {
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- log.Printf("ok: %d, ko: %d", ok, ko)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", mux)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/main.go
deleted file mode 100644
index f43cdc122..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/main.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/http"
- "sync"
- "time"
-
- "gopkg.in/throttled/throttled.v1"
-)
-
-var (
- delay = flag.Duration("delay", 200*time.Millisecond, "delay between calls")
- bursts = flag.Int("bursts", 10, "number of bursts allowed")
- maxkeys = flag.Int("max-keys", 1000, "maximum number of keys")
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-func main() {
- flag.Parse()
-
- var h http.Handler
- var ok, ko int
- var mu sync.Mutex
-
- // Keep the start time to print since-time
- start := time.Now()
-
- // Create the interval throttler
- t := throttled.Interval(throttled.D(*delay), *bursts, &throttled.VaryBy{
- Path: true,
- }, *maxkeys)
- // Set the denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("KO: %s", time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
-
- // Throttle the OK handler
- rand.Seed(time.Now().Unix())
- h = t.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("%s: ok: %s", r.URL.Path, time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- w.WriteHeader(200)
- mu.Lock()
- defer mu.Unlock()
- ok++
- }))
-
- // Print stats once in a while
- go func() {
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- log.Printf("ok: %d, ko: %d", ok, ko)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", h)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/siege-urls b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/siege-urls
deleted file mode 100644
index 9a2d0d312..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval-vary/siege-urls
+++ /dev/null
@@ -1,4 +0,0 @@
-http://localhost:9000/a
-http://localhost:9000/b
-http://localhost:9000/c
-
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval/main.go
deleted file mode 100644
index ef8ee2cb8..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/interval/main.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/http"
- "sync"
- "time"
-
- "gopkg.in/throttled/throttled.v1"
-)
-
-var (
- delay = flag.Duration("delay", 200*time.Millisecond, "delay between calls")
- bursts = flag.Int("bursts", 10, "number of bursts allowed")
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-func main() {
- flag.Parse()
-
- var h http.Handler
- var ok, ko int
- var mu sync.Mutex
-
- // Keep the start time to print since-time
- start := time.Now()
- // Create the interval throttler
- t := throttled.Interval(throttled.D(*delay), *bursts, nil, 0)
- // Set its denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("KO: %s", time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
- // Throttle the OK handler
- rand.Seed(time.Now().Unix())
- h = t.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("ok: %s", time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- w.WriteHeader(200)
- mu.Lock()
- defer mu.Unlock()
- ok++
- }))
-
- // Print stats once in a while
- go func() {
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- log.Printf("ok: %d, ko: %d", ok, ko)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", h)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/main.go
deleted file mode 100644
index 50d4cc69b..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/main.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "io/ioutil"
- "log"
- "math/rand"
- "net/http"
- "runtime"
- "sync"
- "time"
-
- "gopkg.in/throttled/throttled.v1"
-)
-
-var (
- numgc = flag.Int("gc", 0, "number of GC runs")
- mallocs = flag.Int("mallocs", 0, "number of mallocs")
- total = flag.Int("total", 0, "total number of bytes allocated")
- allocs = flag.Int("allocs", 0, "number of bytes allocated")
- refrate = flag.Duration("refresh", 0, "refresh rate of the memory stats")
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-func main() {
- flag.Parse()
-
- var h http.Handler
- var ok, ko int
- var mu sync.Mutex
-
- // Keep the start time to print since-time
- start := time.Now()
- // Create the thresholds struct
- thresh := throttled.MemThresholds(&runtime.MemStats{
- NumGC: uint32(*numgc),
- Mallocs: uint64(*mallocs),
- TotalAlloc: uint64(*total),
- Alloc: uint64(*allocs),
- })
- if *output != "q" {
- log.Printf("thresholds: NumGC: %d, Mallocs: %d, Alloc: %dKb, Total: %dKb", thresh.NumGC, thresh.Mallocs, thresh.Alloc/1024, thresh.TotalAlloc/1024)
- }
- // Create the MemStats throttler
- t := throttled.MemStats(thresh, *refrate)
- // Set its denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("KO: %s", time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
-
- // Throttle the OK handler
- rand.Seed(time.Now().Unix())
- h = t.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("ok: %s", time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- // Read the whole file in memory, to actually use 64Kb (instead of streaming to w)
- b, err := ioutil.ReadFile("test-file")
- if err != nil {
- throttled.Error(w, r, err)
- return
- }
- _, err = w.Write(b)
- if err != nil {
- throttled.Error(w, r, err)
- }
- mu.Lock()
- defer mu.Unlock()
- ok++
- }))
-
- // Print stats once in a while
- go func() {
- var mem runtime.MemStats
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- runtime.ReadMemStats(&mem)
- log.Printf("ok: %d, ko: %d", ok, ko)
- log.Printf("TotalAllocs: %d Kb, Allocs: %d Kb, Mallocs: %d, NumGC: %d", mem.TotalAlloc/1024, mem.Alloc/1024, mem.Mallocs, mem.NumGC)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", h)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/test-file b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/test-file
deleted file mode 100644
index c97c12f9b..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/memstats/test-file
+++ /dev/null
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/rate-limit/main.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/rate-limit/main.go
deleted file mode 100644
index b00119f63..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/examples/rate-limit/main.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/http"
- "sync"
- "time"
-
- "github.com/garyburd/redigo/redis"
- "gopkg.in/throttled/throttled.v1"
- "gopkg.in/throttled/throttled.v1/store"
-)
-
-var (
- requests = flag.Int("requests", 10, "number of requests allowed in the time window")
- window = flag.Duration("window", time.Minute, "time window for the limit of requests")
- storeType = flag.String("store", "mem", "store to use, one of `mem` or `redis` (on default localhost port)")
- delayRes = flag.Duration("delay-response", 0, "delay the response by a random duration between 0 and this value")
- output = flag.String("output", "v", "type of output, one of `v`erbose, `q`uiet, `ok`-only, `ko`-only")
-)
-
-func main() {
- flag.Parse()
-
- var h http.Handler
- var ok, ko int
- var mu sync.Mutex
- var st throttled.Store
-
- // Keep the start time to print since-time
- start := time.Now()
- // Create the rate-limit store
- switch *storeType {
- case "mem":
- st = store.NewMemStore(0)
- case "redis":
- st = store.NewRedisStore(setupRedis(), "throttled:", 0)
- default:
- log.Fatalf("unsupported store: %s", *storeType)
- }
- // Create the rate-limit throttler, varying on path
- t := throttled.RateLimit(throttled.Q{Requests: *requests, Window: *window}, &throttled.VaryBy{
- Path: true,
- }, st)
-
- // Set its denied handler
- t.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ko" {
- log.Printf("KO: %s", time.Since(start))
- }
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- mu.Lock()
- defer mu.Unlock()
- ko++
- })
-
- // Throttle the OK handler
- rand.Seed(time.Now().Unix())
- h = t.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if *output == "v" || *output == "ok" {
- log.Printf("ok: %s", time.Since(start))
- }
- if *delayRes > 0 {
- wait := time.Duration(rand.Intn(int(*delayRes)))
- time.Sleep(wait)
- }
- w.WriteHeader(200)
- mu.Lock()
- defer mu.Unlock()
- ok++
- }))
-
- // Print stats once in a while
- go func() {
- for _ = range time.Tick(10 * time.Second) {
- mu.Lock()
- log.Printf("ok: %d, ko: %d", ok, ko)
- mu.Unlock()
- }
- }()
- fmt.Println("server listening on port 9000")
- http.ListenAndServe(":9000", h)
-}
-
-func setupRedis() *redis.Pool {
- pool := &redis.Pool{
- MaxIdle: 3,
- IdleTimeout: 30 * time.Second,
- Dial: func() (redis.Conn, error) {
- return redis.Dial("tcp", ":6379")
- },
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
- _, err := c.Do("PING")
- return err
- },
- }
- return pool
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/interval.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/interval.go
deleted file mode 100644
index 628a5593e..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/interval.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package throttled
-
-import (
- "net/http"
- "sync"
- "time"
-
- "github.com/golang/groupcache/lru"
-)
-
-// Static check to ensure that the interval limiters implement the Limiter interface.
-var _ Limiter = (*intervalVaryByLimiter)(nil)
-var _ Limiter = (*intervalLimiter)(nil)
-
-// Interval creates a throttler that controls the requests so that they
-// go through at a constant interval. The interval is specified by the
-// delay argument, and convenience types such as PerSec can be used to
-// express the interval in a more expressive way, i.e. PerSec(10) means
-// 10 requests per second or one request each 100ms, PerMin(30) means
-// 30 requests per minute or on request each 2s, etc.
-//
-// The bursts argument indicates the number of exceeding requests that may
-// be queued up waiting to be processed. Requests that overflow the queue
-// are dropped and go through the denied handler, which may be specified
-// on the Throttler and that defaults to the package-global variable
-// DefaultDeniedHandler.
-//
-// The vary argument indicates the criteria to use to group the requests,
-// so that the interval applies to the requests in the same group (e.g. based on
-// the path, or the remote IP address, etc.). If this argument is nil, the
-// interval applies to all requests going through this throttler.
-//
-// The maxKeys indicates the maximum number of keys to keep in memory to apply the interval,
-// when a vary argument is specified. A LRU algorithm is used to remove older keys.
-//
-func Interval(delay Delayer, bursts int, vary *VaryBy, maxKeys int) *Throttler {
- var l Limiter
- if vary != nil {
- if maxKeys < 1 {
- maxKeys = 1
- }
- l = &intervalVaryByLimiter{
- delay: delay.Delay(),
- bursts: bursts,
- vary: vary,
- maxKeys: maxKeys,
- }
- } else {
- l = &intervalLimiter{
- delay: delay.Delay(),
- bursts: bursts,
- }
- }
- return &Throttler{
- limiter: l,
- }
-}
-
-// The intervalLimiter struct implements an interval limiter with no vary-by
-// criteria.
-type intervalLimiter struct {
- delay time.Duration
- bursts int
-
- bucket chan chan bool
-}
-
-// Start initializes the limiter for execution.
-func (il *intervalLimiter) Start() {
- if il.bursts < 0 {
- il.bursts = 0
- }
- il.bucket = make(chan chan bool, il.bursts)
- go process(il.bucket, il.delay)
-}
-
-// Limit is called for each request to the throttled handler. It tries to
-// queue the request to allow it to run at the given interval, but if the
-// queue is full, the request is denied access.
-func (il *intervalLimiter) Limit(w http.ResponseWriter, r *http.Request) (<-chan bool, error) {
- ch := make(chan bool, 1)
- select {
- case il.bucket <- ch:
- return ch, nil
- default:
- ch <- false
- return ch, nil
- }
-}
-
-// The intervalVaryByLimiter struct implements an interval limiter with a vary-by
-// criteria.
-type intervalVaryByLimiter struct {
- delay time.Duration
- bursts int
- vary *VaryBy
-
- lock sync.RWMutex
- keys *lru.Cache
- maxKeys int
-}
-
-// Start initializes the limiter for execution.
-func (il *intervalVaryByLimiter) Start() {
- if il.bursts < 0 {
- il.bursts = 0
- }
- il.keys = lru.New(il.maxKeys)
- il.keys.OnEvicted = il.stopProcess
-}
-
-// Limit is called for each request to the throttled handler. It tries to
-// queue the request for the vary-by key to allow it to run at the given interval,
-// but if the queue is full, the request is denied access.
-func (il *intervalVaryByLimiter) Limit(w http.ResponseWriter, r *http.Request) (<-chan bool, error) {
- ch := make(chan bool, 1)
- key := il.vary.Key(r)
-
- il.lock.RLock()
- item, ok := il.keys.Get(key)
- if !ok {
- // Create the key, bucket, start goroutine
- // First release the read lock and acquire a write lock
- il.lock.RUnlock()
- il.lock.Lock()
- // Create the bucket, add the key
- bucket := make(chan chan bool, il.bursts)
- il.keys.Add(key, bucket)
- // Start the goroutine to process this bucket
- go process(bucket, il.delay)
- item = bucket
- // Release the write lock, acquire the read lock
- il.lock.Unlock()
- il.lock.RLock()
- }
- defer il.lock.RUnlock()
- bucket := item.(chan chan bool)
- select {
- case bucket <- ch:
- return ch, nil
- default:
- ch <- false
- return ch, nil
- }
-}
-
-// process loops through the queued requests for a key's bucket, and sends
-// requests through at the given interval.
-func process(bucket chan chan bool, delay time.Duration) {
- after := time.After(0)
- for v := range bucket {
- <-after
- // Let the request go through
- v <- true
- // Wait the required duration
- after = time.After(delay)
- }
-}
-
-// stopProcess is called when a key is removed from the LRU cache so that its
-// accompanying goroutine is correctly released.
-func (il *intervalVaryByLimiter) stopProcess(key lru.Key, value interface{}) {
- close(value.(chan chan bool))
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/memstats.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/memstats.go
deleted file mode 100644
index bd2765630..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/memstats.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package throttled
-
-import (
- "net/http"
- "runtime"
- "sync"
- "time"
-)
-
-// Static check to ensure that memStatsLimiter implements Limiter.
-var _ Limiter = (*memStatsLimiter)(nil)
-
-// The memStatsLimiter struct implements a limiter based on the memory statistics
-// of the current process.
-type memStatsLimiter struct {
- thresholds *runtime.MemStats
- refreshRate time.Duration
-
- lockStats sync.RWMutex
- stats runtime.MemStats
-}
-
-// MemStats creates a Throttler based on the memory statistics of the current process.
-// Any combination of any (non-array) integer field of Go's runtime.MemStats structure
-// can be used as thresholds to deny a request.
-//
-// As soon as one threshold value is reached, the access is denied. If the value can
-// decrease, access will be allowed again once it gets back under the threshold value.
-// Denied requests go through the denied handler, which may be specified on the Throttler
-// and that defaults to the package-global variable DefaultDeniedHandler.
-//
-// Thresholds must be specified in absolute numbers (i.e. NumGC = 10 means stop once the
-// NumGC reaches 10, not when the current value increments by 10), and zero values are
-// ignored.
-//
-// The refreshRate indicates the frequency at which the process' memory stats are refreshed,
-// and 0 means on each request.
-//
-func MemStats(thresholds *runtime.MemStats, refreshRate time.Duration) *Throttler {
- return &Throttler{
- limiter: &memStatsLimiter{
- thresholds: thresholds,
- refreshRate: refreshRate,
- },
- }
-}
-
-// Start initialized the limiter for execution.
-func (m *memStatsLimiter) Start() {
- // Make sure there is an initial MemStats reading
- runtime.ReadMemStats(&m.stats)
- if m.refreshRate > 0 {
- go m.refresh()
- }
-}
-
-// refresh runs in a separate goroutine and refreshes the memory statistics
-// at regular intervals.
-func (m *memStatsLimiter) refresh() {
- c := time.Tick(m.refreshRate)
- for _ = range c {
- m.lockStats.Lock()
- runtime.ReadMemStats(&m.stats)
- m.lockStats.Unlock()
- }
-}
-
-// Limit is called for each request to the throttled handler. It checks if
-// the request can go through by checking the memory thresholds, and signals it
-// via the returned channel.
-func (m *memStatsLimiter) Limit(w http.ResponseWriter, r *http.Request) (<-chan bool, error) {
- ch := make(chan bool, 1)
- // Check if memory thresholds are reached
- ch <- m.allow()
- return ch, nil
-}
-
-// allow compares the current memory stats with the thresholds, and returns
-// false if any threshold is reached.
-func (m *memStatsLimiter) allow() bool {
- m.lockStats.RLock()
- mem := m.stats
- m.lockStats.RUnlock()
- // If refreshRate == 0, then read on every request.
- if m.refreshRate == 0 {
- runtime.ReadMemStats(&mem)
- }
- ok := true
- checkStat(m.thresholds.Alloc, mem.Alloc, &ok)
- checkStat(m.thresholds.BuckHashSys, mem.BuckHashSys, &ok)
- checkStat(m.thresholds.Frees, mem.Frees, &ok)
- checkStat(m.thresholds.GCSys, mem.GCSys, &ok)
- checkStat(m.thresholds.HeapAlloc, mem.HeapAlloc, &ok)
- checkStat(m.thresholds.HeapIdle, mem.HeapIdle, &ok)
- checkStat(m.thresholds.HeapInuse, mem.HeapInuse, &ok)
- checkStat(m.thresholds.HeapObjects, mem.HeapObjects, &ok)
- checkStat(m.thresholds.HeapReleased, mem.HeapReleased, &ok)
- checkStat(m.thresholds.HeapSys, mem.HeapSys, &ok)
- checkStat(m.thresholds.LastGC, mem.LastGC, &ok)
- checkStat(m.thresholds.Lookups, mem.Lookups, &ok)
- checkStat(m.thresholds.MCacheInuse, mem.MCacheInuse, &ok)
- checkStat(m.thresholds.MCacheSys, mem.MCacheSys, &ok)
- checkStat(m.thresholds.MSpanInuse, mem.MSpanInuse, &ok)
- checkStat(m.thresholds.MSpanSys, mem.MSpanSys, &ok)
- checkStat(m.thresholds.Mallocs, mem.Mallocs, &ok)
- checkStat(m.thresholds.NextGC, mem.NextGC, &ok)
- checkStat(uint64(m.thresholds.NumGC), uint64(mem.NumGC), &ok)
- checkStat(m.thresholds.OtherSys, mem.OtherSys, &ok)
- checkStat(m.thresholds.PauseTotalNs, mem.PauseTotalNs, &ok)
- checkStat(m.thresholds.StackInuse, mem.StackInuse, &ok)
- checkStat(m.thresholds.StackSys, mem.StackSys, &ok)
- checkStat(m.thresholds.Sys, mem.Sys, &ok)
- checkStat(m.thresholds.TotalAlloc, mem.TotalAlloc, &ok)
- return ok
-}
-
-// Checks the threshold value against the actual value, and assigns false
-// to the boolean pointer if the threshold is reached.
-func checkStat(threshold, actual uint64, ok *bool) {
- if !*ok {
- return
- }
- if threshold > 0 {
- if actual >= threshold {
- *ok = false
- }
- }
-}
-
-// MemThresholds is a convenience function to create a thresholds memory stats from
-// offsets to apply to the current memory stats. Zero values in the offset stats
-// are left to 0 in the resulting thresholds memory stats value.
-//
-// The return value may be used as thresholds argument to the MemStats function.
-func MemThresholds(offset *runtime.MemStats) *runtime.MemStats {
- var mem, thr runtime.MemStats
- runtime.ReadMemStats(&mem)
- if offset.Alloc > 0 {
- thr.Alloc = mem.Alloc + offset.Alloc
- }
- if offset.BuckHashSys > 0 {
- thr.BuckHashSys = mem.BuckHashSys + offset.BuckHashSys
- }
- if offset.Frees > 0 {
- thr.Frees = mem.Frees + offset.Frees
- }
- if offset.GCSys > 0 {
- thr.GCSys = mem.GCSys + offset.GCSys
- }
- if offset.HeapAlloc > 0 {
- thr.HeapAlloc = mem.HeapAlloc + offset.HeapAlloc
- }
- if offset.HeapIdle > 0 {
- thr.HeapIdle = mem.HeapIdle + offset.HeapIdle
- }
- if offset.HeapInuse > 0 {
- thr.HeapInuse = mem.HeapInuse + offset.HeapInuse
- }
- if offset.HeapObjects > 0 {
- thr.HeapObjects = mem.HeapObjects + offset.HeapObjects
- }
- if offset.HeapReleased > 0 {
- thr.HeapReleased = mem.HeapReleased + offset.HeapReleased
- }
- if offset.HeapSys > 0 {
- thr.HeapSys = mem.HeapSys + offset.HeapSys
- }
- if offset.LastGC > 0 {
- thr.LastGC = mem.LastGC + offset.LastGC
- }
- if offset.Lookups > 0 {
- thr.Lookups = mem.Lookups + offset.Lookups
- }
- if offset.MCacheInuse > 0 {
- thr.MCacheInuse = mem.MCacheInuse + offset.MCacheInuse
- }
- if offset.MCacheSys > 0 {
- thr.MCacheSys = mem.MCacheSys + offset.MCacheSys
- }
- if offset.MSpanInuse > 0 {
- thr.MSpanInuse = mem.MSpanInuse + offset.MSpanInuse
- }
- if offset.MSpanSys > 0 {
- thr.MSpanSys = mem.MSpanSys + offset.MSpanSys
- }
- if offset.Mallocs > 0 {
- thr.Mallocs = mem.Mallocs + offset.Mallocs
- }
- if offset.NextGC > 0 {
- thr.NextGC = mem.NextGC + offset.NextGC
- }
- if offset.NumGC > 0 {
- thr.NumGC = mem.NumGC + offset.NumGC
- }
- if offset.OtherSys > 0 {
- thr.OtherSys = mem.OtherSys + offset.OtherSys
- }
- if offset.PauseTotalNs > 0 {
- thr.PauseTotalNs = mem.PauseTotalNs + offset.PauseTotalNs
- }
- if offset.StackInuse > 0 {
- thr.StackInuse = mem.StackInuse + offset.StackInuse
- }
- if offset.StackSys > 0 {
- thr.StackSys = mem.StackSys + offset.StackSys
- }
- if offset.Sys > 0 {
- thr.Sys = mem.Sys + offset.Sys
- }
- if offset.TotalAlloc > 0 {
- thr.TotalAlloc = mem.TotalAlloc + offset.TotalAlloc
- }
- return &thr
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/misc/pre-commit b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/misc/pre-commit
deleted file mode 100644
index 88b61bfde..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/misc/pre-commit
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# git gofmt pre-commit hook
-#
-# To use, store as .git/hooks/pre-commit inside your repository and make sure
-# it has execute permissions.
-#
-# This script does not handle file names that contain spaces.
-
-# golint is purely informational, it doesn't fail with exit code != 0 if it finds something,
-# because it may find a lot of false positives. Just print out its result for information.
-echo "lint result (informational only):"
-echo
-golint .
-
-# go vet returns 1 if an error was found. Exit the hook with this exit code.
-go vet ./...
-vetres=$?
-
-# Check for gofmt problems and report if any.
-gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '.go$')
-[ -z "$gofiles" ] && echo "EXIT $vetres" && exit $vetres
-
-unformatted=$(gofmt -l $gofiles)
-[ -z "$unformatted" ] && echo "EXIT $vetres" && exit $vetres
-
-# Some files are not gofmt'd. Print message and fail.
-
-echo >&2 "Go files must be formatted with gofmt. Please run:"
-for fn in $unformatted; do
- echo >&2 " gofmt -w $PWD/$fn"
-done
-
-echo "EXIT 1"
-exit 1
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go
deleted file mode 100644
index d7a7de6d7..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package throttled
-
-import (
- "math"
- "net/http"
- "strconv"
- "time"
-)
-
-// Static check to ensure that rateLimiter implements Limiter.
-var _ Limiter = (*rateLimiter)(nil)
-
-// RateLimit creates a throttler that limits the number of requests allowed
-// in a certain time window defined by the Quota q. The q parameter specifies
-// the requests per time window, and it is silently set to at least 1 request
-// and at least a 1 second window if it is less than that. The time window
-// starts when the first request is made outside an existing window. Fractions
-// of seconds are not supported, they are truncated.
-//
-// The vary parameter indicates what criteria should be used to group requests
-// for which the limit must be applied (ex.: rate limit based on the remote address).
-// See varyby.go for the various options.
-//
-// The specified store is used to keep track of the request count and the
-// time remaining in the window. The throttled package comes with some stores
-// in the throttled/store package. Custom stores can be created too, by implementing
-// the Store interface.
-//
-// Requests that bust the rate limit are denied access and go through the denied handler,
-// which may be specified on the Throttler and that defaults to the package-global
-// variable DefaultDeniedHandler.
-//
-// The rate limit throttler sets the following headers on the response:
-//
-// X-RateLimit-Limit : quota
-// X-RateLimit-Remaining : number of requests remaining in the current window
-// X-RateLimit-Reset : seconds before a new window
-//
-// Additionally, if the request was denied access, the following header is added:
-//
-// Retry-After : seconds before the caller should retry
-//
-func RateLimit(q Quota, vary *VaryBy, store Store) *Throttler {
- // Extract requests and window
- reqs, win := q.Quota()
-
- // Create and return the throttler
- return &Throttler{
- limiter: &rateLimiter{
- reqs: reqs,
- window: win,
- vary: vary,
- store: store,
- },
- }
-}
-
-// The rate limiter implements limiting the request to a certain quota
-// based on the vary-by criteria. State is saved in the store.
-type rateLimiter struct {
- reqs int
- window time.Duration
- vary *VaryBy
- store Store
-}
-
-// Start initializes the limiter for execution.
-func (r *rateLimiter) Start() {
- if r.reqs < 1 {
- r.reqs = 1
- }
- if r.window < time.Second {
- r.window = time.Second
- }
-}
-
-// Limit is called for each request to the throttled handler. It checks if
-// the request can go through and signals it via the returned channel.
-// It returns an error if the operation fails.
-func (r *rateLimiter) Limit(w http.ResponseWriter, req *http.Request) (<-chan bool, error) {
- // Create return channel and initialize
- ch := make(chan bool, 1)
- ok := true
- key := r.vary.Key(req)
-
- // Get the current count and remaining seconds
- cnt, secs, err := r.store.Incr(key, r.window)
- // Handle the possible situations: error, begin new window, or increment current window.
- switch {
- case err != nil && err != ErrNoSuchKey:
- // An unexpected error occurred
- return nil, err
- case err == ErrNoSuchKey || secs <= 0:
- // Reset counter
- if err := r.store.Reset(key, r.window); err != nil {
- return nil, err
- }
- cnt = 1
- secs = int(r.window.Seconds())
- default:
- // If the limit is reached, deny access
- if cnt > r.reqs {
- ok = false
- }
- }
- // Set rate-limit headers
- w.Header().Add("X-RateLimit-Limit", strconv.Itoa(r.reqs))
- w.Header().Add("X-RateLimit-Remaining", strconv.Itoa(int(math.Max(float64(r.reqs-cnt), 0))))
- w.Header().Add("X-RateLimit-Reset", strconv.Itoa(secs))
- if !ok {
- w.Header().Add("Retry-After", strconv.Itoa(secs))
- }
- // Send response via the return channel
- ch <- ok
- return ch, nil
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store.go
deleted file mode 100644
index 760fe2b69..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package throttled
-
-import (
- "errors"
- "time"
-)
-
-// The error returned if the key does not exist in the Store.
-var ErrNoSuchKey = errors.New("throttled: no such key")
-
-// Store is the interface to implement to store the RateLimit state (number
-// of requests per key, time-to-live or creation timestamp).
-type Store interface {
- // Incr increments the count for the specified key and returns the new value along
- // with the number of seconds remaining. It may return an error
- // if the operation fails.
- //
- // The method may return ErrNoSuchKey if the key to increment does not exist,
- // in which case Reset will be called to initialize the value.
- Incr(string, time.Duration) (int, int, error)
-
- // Reset resets the key to 1 with the specified window duration. It must create the
- // key if it doesn't exist. It returns an error if it fails.
- Reset(string, time.Duration) error
-}
-
-// RemainingSeconds is a helper function that returns the number of seconds
-// remaining from an absolute timestamp in UTC.
-func RemainingSeconds(ts time.Time, window time.Duration) int {
- return int((window - time.Now().UTC().Sub(ts)).Seconds())
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/doc.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/doc.go
deleted file mode 100644
index adb4618d3..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package store offers a memory-based and a Redis-based throttled.Store implementation.
-package store
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/mem.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/mem.go
deleted file mode 100644
index 22d200e8d..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/mem.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package store
-
-import (
- "sync"
- "time"
-
- "github.com/golang/groupcache/lru"
- "gopkg.in/throttled/throttled.v1"
-)
-
-// memStore implements an in-memory Store.
-type memStore struct {
- sync.Mutex
- keys *lru.Cache
- m map[string]*counter
-}
-
-// NewMemStore creates a new MemStore. If maxKeys > 0, the number of different keys
-// is restricted to the specified amount. In this case, it uses an LRU algorithm to
-// evict older keys to make room for newer ones. If a request is made for a key that
-// has been evicted, it will be processed as if its count was 0, possibly allowing requests
-// that should be denied.
-//
-// If maxKeys <= 0, there is no limit on the number of keys, which may use an unbounded amount of
-// memory depending on the server's load.
-//
-// The MemStore is only for single-process rate-limiting. To share the rate limit state
-// among multiple instances of the web server, use a database- or key-value-based
-// store.
-//
-func NewMemStore(maxKeys int) throttled.Store {
- var m *memStore
- if maxKeys > 0 {
- m = &memStore{
- keys: lru.New(maxKeys),
- }
- } else {
- m = &memStore{
- m: make(map[string]*counter),
- }
- }
- return m
-}
-
-// A counter represents a single entry in the MemStore.
-type counter struct {
- n int
- ts time.Time
-}
-
-// Incr increments the counter for the specified key. It returns the new
-// count value and the remaining number of seconds, or an error.
-func (ms *memStore) Incr(key string, window time.Duration) (int, int, error) {
- ms.Lock()
- defer ms.Unlock()
- var c *counter
- if ms.keys != nil {
- v, _ := ms.keys.Get(key)
- if v != nil {
- c = v.(*counter)
- }
- } else {
- c = ms.m[key]
- }
- if c == nil {
- c = &counter{0, time.Now().UTC()}
- }
- c.n++
- if ms.keys != nil {
- ms.keys.Add(key, c)
- } else {
- ms.m[key] = c
- }
- return c.n, throttled.RemainingSeconds(c.ts, window), nil
-}
-
-// Reset resets the counter for the specified key. It sets the count
-// to 1 and initializes the timestamp with the current time, in UTC.
-// It returns an error if the operation fails.
-func (ms *memStore) Reset(key string, win time.Duration) error {
- ms.Lock()
- defer ms.Unlock()
- c := &counter{1, time.Now().UTC()}
- if ms.keys != nil {
- ms.keys.Add(key, c)
- } else {
- ms.m[key] = c
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/redis.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/redis.go
deleted file mode 100644
index b089f9f4e..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/store/redis.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-import (
- "time"
-
- "github.com/garyburd/redigo/redis"
- "gopkg.in/throttled/throttled.v1"
-)
-
-// redisStore implements a Redis-based store.
-type redisStore struct {
- pool *redis.Pool
- prefix string
- db int
-}
-
-// NewRedisStore creates a new Redis-based store, using the provided pool to get its
-// connections. The keys will have the specified keyPrefix, which may be an empty string,
-// and the database index specified by db will be selected to store the keys.
-//
-func NewRedisStore(pool *redis.Pool, keyPrefix string, db int) throttled.Store {
- return &redisStore{
- pool: pool,
- prefix: keyPrefix,
- db: db,
- }
-}
-
-// Incr increments the specified key. If the key did not exist, it sets it to 1
-// and sets it to expire after the number of seconds specified by window.
-//
-// It returns the new count value and the number of remaining seconds, or an error
-// if the operation fails.
-func (r *redisStore) Incr(key string, window time.Duration) (int, int, error) {
- conn := r.pool.Get()
- defer conn.Close()
- if err := selectDB(r.db, conn); err != nil {
- return 0, 0, err
- }
- // Atomically increment and read the TTL.
- conn.Send("MULTI")
- conn.Send("INCR", r.prefix+key)
- conn.Send("TTL", r.prefix+key)
- vals, err := redis.Values(conn.Do("EXEC"))
- if err != nil {
- conn.Do("DISCARD")
- return 0, 0, err
- }
- var cnt, ttl int
- if _, err = redis.Scan(vals, &cnt, &ttl); err != nil {
- return 0, 0, err
- }
- // If there was no TTL set, then this is a newly created key (INCR creates the key
- // if it didn't exist), so set it to expire.
- if ttl == -1 {
- ttl = int(window.Seconds())
- _, err = conn.Do("EXPIRE", r.prefix+key, ttl)
- if err != nil {
- return 0, 0, err
- }
- }
- return cnt, ttl, nil
-}
-
-// Reset sets the value of the key to 1, and resets its time window.
-func (r *redisStore) Reset(key string, window time.Duration) error {
- conn := r.pool.Get()
- defer conn.Close()
- if err := selectDB(r.db, conn); err != nil {
- return err
- }
- _, err := redis.String(conn.Do("SET", r.prefix+key, "1", "EX", int(window.Seconds()), "NX"))
- return err
-}
-
-// Select the specified database index.
-func selectDB(db int, conn redis.Conn) error {
- // Select the specified database
- if db > 0 {
- if _, err := redis.String(conn.Do("SELECT", db)); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/throttler.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/throttler.go
deleted file mode 100644
index 06da13051..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/throttler.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package throttled
-
-import (
- "net/http"
- "sync"
-)
-
-var (
- // DefaultDeniedHandler handles the requests that were denied access because
- // of a throttler. By default, returns a 429 status code with a
- // generic message.
- DefaultDeniedHandler = http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- http.Error(w, "limit exceeded", 429)
- }))
-
- // Error is the function to call when an error occurs on a throttled handler.
- // By default, returns a 500 status code with a generic message.
- Error = ErrorFunc(func(w http.ResponseWriter, r *http.Request, err error) {
- http.Error(w, "internal error", http.StatusInternalServerError)
- })
-)
-
-// ErrorFunc defines the function type for the Error variable.
-type ErrorFunc func(w http.ResponseWriter, r *http.Request, err error)
-
-// The Limiter interface defines the methods required to control access to a
-// throttled handler.
-type Limiter interface {
- Start()
- Limit(http.ResponseWriter, *http.Request) (<-chan bool, error)
-}
-
-// Custom creates a Throttler using the provided Limiter implementation.
-func Custom(l Limiter) *Throttler {
- return &Throttler{
- limiter: l,
- }
-}
-
-// A Throttler controls access to HTTP handlers using a Limiter.
-type Throttler struct {
- // DeniedHandler is called if the request is disallowed. If it is nil,
- // the DefaultDeniedHandler variable is used.
- DeniedHandler http.Handler
-
- limiter Limiter
- // The mutex protects the started flag
- mu sync.Mutex
- started bool
-}
-
-// Throttle wraps a HTTP handler so that its access is controlled by
-// the Throttler. It returns the Handler with the throttling logic.
-func (t *Throttler) Throttle(h http.Handler) http.Handler {
- dh := t.start()
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- ch, err := t.limiter.Limit(w, r)
- if err != nil {
- Error(w, r, err)
- return
- }
- ok := <-ch
- if ok {
- h.ServeHTTP(w, r)
- } else {
- dh.ServeHTTP(w, r)
- }
- })
-}
-
-// start starts the throttling and returns the effective denied handler to
-// use for requests that were denied access.
-func (t *Throttler) start() http.Handler {
- t.mu.Lock()
- defer t.mu.Unlock()
- // Get the effective denied handler
- dh := t.DeniedHandler
- if dh == nil {
- dh = DefaultDeniedHandler
- }
- if !t.started {
- t.limiter.Start()
- t.started = true
- }
- return dh
-}
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/varyby.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/varyby.go
deleted file mode 100644
index 3b2cdb011..000000000
--- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/varyby.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package throttled
-
-import (
- "bytes"
- "net/http"
- "strings"
-)
-
-// VaryBy defines the criteria to use to group requests.
-type VaryBy struct {
- // Vary by the RemoteAddr as specified by the net/http.Request field.
- RemoteAddr bool
-
- // Vary by the HTTP Method as specified by the net/http.Request field.
- Method bool
-
- // Vary by the URL's Path as specified by the Path field of the net/http.Request
- // URL field.
- Path bool
-
- // Vary by this list of header names, read from the net/http.Request Header field.
- Headers []string
-
- // Vary by this list of parameters, read from the net/http.Request FormValue method.
- Params []string
-
- // Vary by this list of cookie names, read from the net/http.Request Cookie method.
- Cookies []string
-
- // Use this separator string to concatenate the various criteria of the VaryBy struct.
- // Defaults to a newline character if empty (\n).
- Separator string
-
- // Custom specifies the custom-generated key to use for this request.
- // If not nil, the value returned by this function is used instead of any
- // VaryBy criteria.
- Custom func(r *http.Request) string
-}
-
-// Key returns the key for this request based on the criteria defined by the VaryBy struct.
-func (vb *VaryBy) Key(r *http.Request) string {
- var buf bytes.Buffer
-
- if vb == nil {
- return "" // Special case for no vary-by option
- }
- if vb.Custom != nil {
- // A custom key generator is specified
- return vb.Custom(r)
- }
- sep := vb.Separator
- if sep == "" {
- sep = "\n" // Separator defaults to newline
- }
- if vb.RemoteAddr {
- buf.WriteString(strings.ToLower(r.RemoteAddr) + sep)
- }
- if vb.Method {
- buf.WriteString(strings.ToLower(r.Method) + sep)
- }
- for _, h := range vb.Headers {
- buf.WriteString(strings.ToLower(r.Header.Get(h)) + sep)
- }
- if vb.Path {
- buf.WriteString(r.URL.Path + sep)
- }
- for _, p := range vb.Params {
- buf.WriteString(r.FormValue(p) + sep)
- }
- for _, c := range vb.Cookies {
- ck, err := r.Cookie(c)
- if err == nil {
- buf.WriteString(ck.Value)
- }
- buf.WriteString(sep) // Write the separator anyway, whether or not the cookie exists
- }
- return buf.String()
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE b/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE
deleted file mode 100644
index a68e67f01..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE
+++ /dev/null
@@ -1,188 +0,0 @@
-
-Copyright (c) 2011-2014 - Canonical Inc.
-
-This software is licensed under the LGPLv3, included below.
-
-As a special exception to the GNU Lesser General Public License version 3
-("LGPL3"), the copyright holders of this Library give you permission to
-convey to a third party a Combined Work that links statically or dynamically
-to this Library without providing any Minimal Corresponding Source or
-Minimal Application Code as set out in 4d or providing the installation
-information set out in section 4e, provided that you comply with the other
-provisions of LGPL3 and provided that you meet, for the Application the
-terms and conditions of the license(s) which apply to the Application.
-
-Except as stated in this special exception, the provisions of LGPL3 will
-continue to comply in full to this Library. If you modify this Library, you
-may apply this exception to your version of this Library, but you are not
-obliged to do so. If you do not wish to do so, delete this exception
-statement from your version. This exception does not (and cannot) modify any
-license terms which apply to the Application, with which you must still
-comply.
-
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml b/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml
deleted file mode 100644
index 8da58fbf6..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml
+++ /dev/null
@@ -1,31 +0,0 @@
-The following files were ported to Go from C files of libyaml, and thus
-are still covered by their original copyright and license:
-
- apic.go
- emitterc.go
- parserc.go
- readerc.go
- scannerc.go
- writerc.go
- yamlh.go
- yamlprivateh.go
-
-Copyright (c) 2006 Kirill Simonov
-
-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.
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/README.md b/Godeps/_workspace/src/gopkg.in/yaml.v2/README.md
deleted file mode 100644
index 7b8bd8670..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/README.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# YAML support for the Go language
-
-Introduction
-------------
-
-The yaml package enables Go programs to comfortably encode and decode YAML
-values. It was developed within [Canonical](https://www.canonical.com) as
-part of the [juju](https://juju.ubuntu.com) project, and is based on a
-pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
-C library to parse and generate YAML data quickly and reliably.
-
-Compatibility
--------------
-
-The yaml package supports most of YAML 1.1 and 1.2, including support for
-anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
-implemented, and base-60 floats from YAML 1.1 are purposefully not
-supported since they're a poor design and are gone in YAML 1.2.
-
-Installation and usage
-----------------------
-
-The import path for the package is *gopkg.in/yaml.v2*.
-
-To install it, run:
-
- go get gopkg.in/yaml.v2
-
-API documentation
------------------
-
-If opened in a browser, the import path itself leads to the API documentation:
-
- * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
-
-API stability
--------------
-
-The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
-
-
-License
--------
-
-The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
-
-
-Example
--------
-
-```Go
-package main
-
-import (
- "fmt"
- "log"
-
- "gopkg.in/yaml.v2"
-)
-
-var data = `
-a: Easy!
-b:
- c: 2
- d: [3, 4]
-`
-
-type T struct {
- A string
- B struct {
- RenamedC int `yaml:"c"`
- D []int `yaml:",flow"`
- }
-}
-
-func main() {
- t := T{}
-
- err := yaml.Unmarshal([]byte(data), &t)
- if err != nil {
- log.Fatalf("error: %v", err)
- }
- fmt.Printf("--- t:\n%v\n\n", t)
-
- d, err := yaml.Marshal(&t)
- if err != nil {
- log.Fatalf("error: %v", err)
- }
- fmt.Printf("--- t dump:\n%s\n\n", string(d))
-
- m := make(map[interface{}]interface{})
-
- err = yaml.Unmarshal([]byte(data), &m)
- if err != nil {
- log.Fatalf("error: %v", err)
- }
- fmt.Printf("--- m:\n%v\n\n", m)
-
- d, err = yaml.Marshal(&m)
- if err != nil {
- log.Fatalf("error: %v", err)
- }
- fmt.Printf("--- m dump:\n%s\n\n", string(d))
-}
-```
-
-This example will generate the following output:
-
-```
---- t:
-{Easy! {2 [3 4]}}
-
---- t dump:
-a: Easy!
-b:
- c: 2
- d: [3, 4]
-
-
---- m:
-map[a:Easy! b:map[c:2 d:[3 4]]]
-
---- m dump:
-a: Easy!
-b:
- c: 2
- d:
- - 3
- - 4
-```
-
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/apic.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/apic.go
deleted file mode 100644
index 95ec014e8..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/apic.go
+++ /dev/null
@@ -1,742 +0,0 @@
-package yaml
-
-import (
- "io"
- "os"
-)
-
-func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
- //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
-
- // Check if we can move the queue at the beginning of the buffer.
- if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
- if parser.tokens_head != len(parser.tokens) {
- copy(parser.tokens, parser.tokens[parser.tokens_head:])
- }
- parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
- parser.tokens_head = 0
- }
- parser.tokens = append(parser.tokens, *token)
- if pos < 0 {
- return
- }
- copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
- parser.tokens[parser.tokens_head+pos] = *token
-}
-
-// Create a new parser object.
-func yaml_parser_initialize(parser *yaml_parser_t) bool {
- *parser = yaml_parser_t{
- raw_buffer: make([]byte, 0, input_raw_buffer_size),
- buffer: make([]byte, 0, input_buffer_size),
- }
- return true
-}
-
-// Destroy a parser object.
-func yaml_parser_delete(parser *yaml_parser_t) {
- *parser = yaml_parser_t{}
-}
-
-// String read handler.
-func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
- if parser.input_pos == len(parser.input) {
- return 0, io.EOF
- }
- n = copy(buffer, parser.input[parser.input_pos:])
- parser.input_pos += n
- return n, nil
-}
-
-// File read handler.
-func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
- return parser.input_file.Read(buffer)
-}
-
-// Set a string input.
-func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
- if parser.read_handler != nil {
- panic("must set the input source only once")
- }
- parser.read_handler = yaml_string_read_handler
- parser.input = input
- parser.input_pos = 0
-}
-
-// Set a file input.
-func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
- if parser.read_handler != nil {
- panic("must set the input source only once")
- }
- parser.read_handler = yaml_file_read_handler
- parser.input_file = file
-}
-
-// Set the source encoding.
-func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
- if parser.encoding != yaml_ANY_ENCODING {
- panic("must set the encoding only once")
- }
- parser.encoding = encoding
-}
-
-// Create a new emitter object.
-func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
- *emitter = yaml_emitter_t{
- buffer: make([]byte, output_buffer_size),
- raw_buffer: make([]byte, 0, output_raw_buffer_size),
- states: make([]yaml_emitter_state_t, 0, initial_stack_size),
- events: make([]yaml_event_t, 0, initial_queue_size),
- }
- return true
-}
-
-// Destroy an emitter object.
-func yaml_emitter_delete(emitter *yaml_emitter_t) {
- *emitter = yaml_emitter_t{}
-}
-
-// String write handler.
-func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
- *emitter.output_buffer = append(*emitter.output_buffer, buffer...)
- return nil
-}
-
-// File write handler.
-func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
- _, err := emitter.output_file.Write(buffer)
- return err
-}
-
-// Set a string output.
-func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
- if emitter.write_handler != nil {
- panic("must set the output target only once")
- }
- emitter.write_handler = yaml_string_write_handler
- emitter.output_buffer = output_buffer
-}
-
-// Set a file output.
-func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
- if emitter.write_handler != nil {
- panic("must set the output target only once")
- }
- emitter.write_handler = yaml_file_write_handler
- emitter.output_file = file
-}
-
-// Set the output encoding.
-func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
- if emitter.encoding != yaml_ANY_ENCODING {
- panic("must set the output encoding only once")
- }
- emitter.encoding = encoding
-}
-
-// Set the canonical output style.
-func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
- emitter.canonical = canonical
-}
-
-//// Set the indentation increment.
-func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
- if indent < 2 || indent > 9 {
- indent = 2
- }
- emitter.best_indent = indent
-}
-
-// Set the preferred line width.
-func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
- if width < 0 {
- width = -1
- }
- emitter.best_width = width
-}
-
-// Set if unescaped non-ASCII characters are allowed.
-func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
- emitter.unicode = unicode
-}
-
-// Set the preferred line break character.
-func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
- emitter.line_break = line_break
-}
-
-///*
-// * Destroy a token object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_token_delete(yaml_token_t *token)
-//{
-// assert(token); // Non-NULL token object expected.
-//
-// switch (token.type)
-// {
-// case YAML_TAG_DIRECTIVE_TOKEN:
-// yaml_free(token.data.tag_directive.handle);
-// yaml_free(token.data.tag_directive.prefix);
-// break;
-//
-// case YAML_ALIAS_TOKEN:
-// yaml_free(token.data.alias.value);
-// break;
-//
-// case YAML_ANCHOR_TOKEN:
-// yaml_free(token.data.anchor.value);
-// break;
-//
-// case YAML_TAG_TOKEN:
-// yaml_free(token.data.tag.handle);
-// yaml_free(token.data.tag.suffix);
-// break;
-//
-// case YAML_SCALAR_TOKEN:
-// yaml_free(token.data.scalar.value);
-// break;
-//
-// default:
-// break;
-// }
-//
-// memset(token, 0, sizeof(yaml_token_t));
-//}
-//
-///*
-// * Check if a string is a valid UTF-8 sequence.
-// *
-// * Check 'reader.c' for more details on UTF-8 encoding.
-// */
-//
-//static int
-//yaml_check_utf8(yaml_char_t *start, size_t length)
-//{
-// yaml_char_t *end = start+length;
-// yaml_char_t *pointer = start;
-//
-// while (pointer < end) {
-// unsigned char octet;
-// unsigned int width;
-// unsigned int value;
-// size_t k;
-//
-// octet = pointer[0];
-// width = (octet & 0x80) == 0x00 ? 1 :
-// (octet & 0xE0) == 0xC0 ? 2 :
-// (octet & 0xF0) == 0xE0 ? 3 :
-// (octet & 0xF8) == 0xF0 ? 4 : 0;
-// value = (octet & 0x80) == 0x00 ? octet & 0x7F :
-// (octet & 0xE0) == 0xC0 ? octet & 0x1F :
-// (octet & 0xF0) == 0xE0 ? octet & 0x0F :
-// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-// if (!width) return 0;
-// if (pointer+width > end) return 0;
-// for (k = 1; k < width; k ++) {
-// octet = pointer[k];
-// if ((octet & 0xC0) != 0x80) return 0;
-// value = (value << 6) + (octet & 0x3F);
-// }
-// if (!((width == 1) ||
-// (width == 2 && value >= 0x80) ||
-// (width == 3 && value >= 0x800) ||
-// (width == 4 && value >= 0x10000))) return 0;
-//
-// pointer += width;
-// }
-//
-// return 1;
-//}
-//
-
-// Create STREAM-START.
-func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
- *event = yaml_event_t{
- typ: yaml_STREAM_START_EVENT,
- encoding: encoding,
- }
- return true
-}
-
-// Create STREAM-END.
-func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
- *event = yaml_event_t{
- typ: yaml_STREAM_END_EVENT,
- }
- return true
-}
-
-// Create DOCUMENT-START.
-func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
- tag_directives []yaml_tag_directive_t, implicit bool) bool {
- *event = yaml_event_t{
- typ: yaml_DOCUMENT_START_EVENT,
- version_directive: version_directive,
- tag_directives: tag_directives,
- implicit: implicit,
- }
- return true
-}
-
-// Create DOCUMENT-END.
-func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
- *event = yaml_event_t{
- typ: yaml_DOCUMENT_END_EVENT,
- implicit: implicit,
- }
- return true
-}
-
-///*
-// * Create ALIAS.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
-//{
-// mark yaml_mark_t = { 0, 0, 0 }
-// anchor_copy *yaml_char_t = NULL
-//
-// assert(event) // Non-NULL event object is expected.
-// assert(anchor) // Non-NULL anchor is expected.
-//
-// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
-//
-// anchor_copy = yaml_strdup(anchor)
-// if (!anchor_copy)
-// return 0
-//
-// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
-//
-// return 1
-//}
-
-// Create SCALAR.
-func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
- *event = yaml_event_t{
- typ: yaml_SCALAR_EVENT,
- anchor: anchor,
- tag: tag,
- value: value,
- implicit: plain_implicit,
- quoted_implicit: quoted_implicit,
- style: yaml_style_t(style),
- }
- return true
-}
-
-// Create SEQUENCE-START.
-func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_START_EVENT,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(style),
- }
- return true
-}
-
-// Create SEQUENCE-END.
-func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_END_EVENT,
- }
- return true
-}
-
-// Create MAPPING-START.
-func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
- *event = yaml_event_t{
- typ: yaml_MAPPING_START_EVENT,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(style),
- }
- return true
-}
-
-// Create MAPPING-END.
-func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
- *event = yaml_event_t{
- typ: yaml_MAPPING_END_EVENT,
- }
- return true
-}
-
-// Destroy an event object.
-func yaml_event_delete(event *yaml_event_t) {
- *event = yaml_event_t{}
-}
-
-///*
-// * Create a document object.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_initialize(document *yaml_document_t,
-// version_directive *yaml_version_directive_t,
-// tag_directives_start *yaml_tag_directive_t,
-// tag_directives_end *yaml_tag_directive_t,
-// start_implicit int, end_implicit int)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-// struct {
-// start *yaml_node_t
-// end *yaml_node_t
-// top *yaml_node_t
-// } nodes = { NULL, NULL, NULL }
-// version_directive_copy *yaml_version_directive_t = NULL
-// struct {
-// start *yaml_tag_directive_t
-// end *yaml_tag_directive_t
-// top *yaml_tag_directive_t
-// } tag_directives_copy = { NULL, NULL, NULL }
-// value yaml_tag_directive_t = { NULL, NULL }
-// mark yaml_mark_t = { 0, 0, 0 }
-//
-// assert(document) // Non-NULL document object is expected.
-// assert((tag_directives_start && tag_directives_end) ||
-// (tag_directives_start == tag_directives_end))
-// // Valid tag directives are expected.
-//
-// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
-//
-// if (version_directive) {
-// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
-// if (!version_directive_copy) goto error
-// version_directive_copy.major = version_directive.major
-// version_directive_copy.minor = version_directive.minor
-// }
-//
-// if (tag_directives_start != tag_directives_end) {
-// tag_directive *yaml_tag_directive_t
-// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-// goto error
-// for (tag_directive = tag_directives_start
-// tag_directive != tag_directives_end; tag_directive ++) {
-// assert(tag_directive.handle)
-// assert(tag_directive.prefix)
-// if (!yaml_check_utf8(tag_directive.handle,
-// strlen((char *)tag_directive.handle)))
-// goto error
-// if (!yaml_check_utf8(tag_directive.prefix,
-// strlen((char *)tag_directive.prefix)))
-// goto error
-// value.handle = yaml_strdup(tag_directive.handle)
-// value.prefix = yaml_strdup(tag_directive.prefix)
-// if (!value.handle || !value.prefix) goto error
-// if (!PUSH(&context, tag_directives_copy, value))
-// goto error
-// value.handle = NULL
-// value.prefix = NULL
-// }
-// }
-//
-// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
-// tag_directives_copy.start, tag_directives_copy.top,
-// start_implicit, end_implicit, mark, mark)
-//
-// return 1
-//
-//error:
-// STACK_DEL(&context, nodes)
-// yaml_free(version_directive_copy)
-// while (!STACK_EMPTY(&context, tag_directives_copy)) {
-// value yaml_tag_directive_t = POP(&context, tag_directives_copy)
-// yaml_free(value.handle)
-// yaml_free(value.prefix)
-// }
-// STACK_DEL(&context, tag_directives_copy)
-// yaml_free(value.handle)
-// yaml_free(value.prefix)
-//
-// return 0
-//}
-//
-///*
-// * Destroy a document object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_document_delete(document *yaml_document_t)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-// tag_directive *yaml_tag_directive_t
-//
-// context.error = YAML_NO_ERROR // Eliminate a compliler warning.
-//
-// assert(document) // Non-NULL document object is expected.
-//
-// while (!STACK_EMPTY(&context, document.nodes)) {
-// node yaml_node_t = POP(&context, document.nodes)
-// yaml_free(node.tag)
-// switch (node.type) {
-// case YAML_SCALAR_NODE:
-// yaml_free(node.data.scalar.value)
-// break
-// case YAML_SEQUENCE_NODE:
-// STACK_DEL(&context, node.data.sequence.items)
-// break
-// case YAML_MAPPING_NODE:
-// STACK_DEL(&context, node.data.mapping.pairs)
-// break
-// default:
-// assert(0) // Should not happen.
-// }
-// }
-// STACK_DEL(&context, document.nodes)
-//
-// yaml_free(document.version_directive)
-// for (tag_directive = document.tag_directives.start
-// tag_directive != document.tag_directives.end
-// tag_directive++) {
-// yaml_free(tag_directive.handle)
-// yaml_free(tag_directive.prefix)
-// }
-// yaml_free(document.tag_directives.start)
-//
-// memset(document, 0, sizeof(yaml_document_t))
-//}
-//
-///**
-// * Get a document node.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_node(document *yaml_document_t, index int)
-//{
-// assert(document) // Non-NULL document object is expected.
-//
-// if (index > 0 && document.nodes.start + index <= document.nodes.top) {
-// return document.nodes.start + index - 1
-// }
-// return NULL
-//}
-//
-///**
-// * Get the root object.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_root_node(document *yaml_document_t)
-//{
-// assert(document) // Non-NULL document object is expected.
-//
-// if (document.nodes.top != document.nodes.start) {
-// return document.nodes.start
-// }
-// return NULL
-//}
-//
-///*
-// * Add a scalar node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_scalar(document *yaml_document_t,
-// tag *yaml_char_t, value *yaml_char_t, length int,
-// style yaml_scalar_style_t)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-// mark yaml_mark_t = { 0, 0, 0 }
-// tag_copy *yaml_char_t = NULL
-// value_copy *yaml_char_t = NULL
-// node yaml_node_t
-//
-// assert(document) // Non-NULL document object is expected.
-// assert(value) // Non-NULL value is expected.
-//
-// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
-// }
-//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-// tag_copy = yaml_strdup(tag)
-// if (!tag_copy) goto error
-//
-// if (length < 0) {
-// length = strlen((char *)value)
-// }
-//
-// if (!yaml_check_utf8(value, length)) goto error
-// value_copy = yaml_malloc(length+1)
-// if (!value_copy) goto error
-// memcpy(value_copy, value, length)
-// value_copy[length] = '\0'
-//
-// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
-// if (!PUSH(&context, document.nodes, node)) goto error
-//
-// return document.nodes.top - document.nodes.start
-//
-//error:
-// yaml_free(tag_copy)
-// yaml_free(value_copy)
-//
-// return 0
-//}
-//
-///*
-// * Add a sequence node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_sequence(document *yaml_document_t,
-// tag *yaml_char_t, style yaml_sequence_style_t)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-// mark yaml_mark_t = { 0, 0, 0 }
-// tag_copy *yaml_char_t = NULL
-// struct {
-// start *yaml_node_item_t
-// end *yaml_node_item_t
-// top *yaml_node_item_t
-// } items = { NULL, NULL, NULL }
-// node yaml_node_t
-//
-// assert(document) // Non-NULL document object is expected.
-//
-// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
-// }
-//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-// tag_copy = yaml_strdup(tag)
-// if (!tag_copy) goto error
-//
-// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
-//
-// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
-// style, mark, mark)
-// if (!PUSH(&context, document.nodes, node)) goto error
-//
-// return document.nodes.top - document.nodes.start
-//
-//error:
-// STACK_DEL(&context, items)
-// yaml_free(tag_copy)
-//
-// return 0
-//}
-//
-///*
-// * Add a mapping node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_mapping(document *yaml_document_t,
-// tag *yaml_char_t, style yaml_mapping_style_t)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-// mark yaml_mark_t = { 0, 0, 0 }
-// tag_copy *yaml_char_t = NULL
-// struct {
-// start *yaml_node_pair_t
-// end *yaml_node_pair_t
-// top *yaml_node_pair_t
-// } pairs = { NULL, NULL, NULL }
-// node yaml_node_t
-//
-// assert(document) // Non-NULL document object is expected.
-//
-// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
-// }
-//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-// tag_copy = yaml_strdup(tag)
-// if (!tag_copy) goto error
-//
-// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
-//
-// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
-// style, mark, mark)
-// if (!PUSH(&context, document.nodes, node)) goto error
-//
-// return document.nodes.top - document.nodes.start
-//
-//error:
-// STACK_DEL(&context, pairs)
-// yaml_free(tag_copy)
-//
-// return 0
-//}
-//
-///*
-// * Append an item to a sequence node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_sequence_item(document *yaml_document_t,
-// sequence int, item int)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-//
-// assert(document) // Non-NULL document is required.
-// assert(sequence > 0
-// && document.nodes.start + sequence <= document.nodes.top)
-// // Valid sequence id is required.
-// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
-// // A sequence node is required.
-// assert(item > 0 && document.nodes.start + item <= document.nodes.top)
-// // Valid item id is required.
-//
-// if (!PUSH(&context,
-// document.nodes.start[sequence-1].data.sequence.items, item))
-// return 0
-//
-// return 1
-//}
-//
-///*
-// * Append a pair of a key and a value to a mapping node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_mapping_pair(document *yaml_document_t,
-// mapping int, key int, value int)
-//{
-// struct {
-// error yaml_error_type_t
-// } context
-//
-// pair yaml_node_pair_t
-//
-// assert(document) // Non-NULL document is required.
-// assert(mapping > 0
-// && document.nodes.start + mapping <= document.nodes.top)
-// // Valid mapping id is required.
-// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
-// // A mapping node is required.
-// assert(key > 0 && document.nodes.start + key <= document.nodes.top)
-// // Valid key id is required.
-// assert(value > 0 && document.nodes.start + value <= document.nodes.top)
-// // Valid value id is required.
-//
-// pair.key = key
-// pair.value = value
-//
-// if (!PUSH(&context,
-// document.nodes.start[mapping-1].data.mapping.pairs, pair))
-// return 0
-//
-// return 1
-//}
-//
-//
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go
deleted file mode 100644
index 085cddc44..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go
+++ /dev/null
@@ -1,683 +0,0 @@
-package yaml
-
-import (
- "encoding"
- "encoding/base64"
- "fmt"
- "math"
- "reflect"
- "strconv"
- "time"
-)
-
-const (
- documentNode = 1 << iota
- mappingNode
- sequenceNode
- scalarNode
- aliasNode
-)
-
-type node struct {
- kind int
- line, column int
- tag string
- value string
- implicit bool
- children []*node
- anchors map[string]*node
-}
-
-// ----------------------------------------------------------------------------
-// Parser, produces a node tree out of a libyaml event stream.
-
-type parser struct {
- parser yaml_parser_t
- event yaml_event_t
- doc *node
-}
-
-func newParser(b []byte) *parser {
- p := parser{}
- if !yaml_parser_initialize(&p.parser) {
- panic("failed to initialize YAML emitter")
- }
-
- if len(b) == 0 {
- b = []byte{'\n'}
- }
-
- yaml_parser_set_input_string(&p.parser, b)
-
- p.skip()
- if p.event.typ != yaml_STREAM_START_EVENT {
- panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
- }
- p.skip()
- return &p
-}
-
-func (p *parser) destroy() {
- if p.event.typ != yaml_NO_EVENT {
- yaml_event_delete(&p.event)
- }
- yaml_parser_delete(&p.parser)
-}
-
-func (p *parser) skip() {
- if p.event.typ != yaml_NO_EVENT {
- if p.event.typ == yaml_STREAM_END_EVENT {
- failf("attempted to go past the end of stream; corrupted value?")
- }
- yaml_event_delete(&p.event)
- }
- if !yaml_parser_parse(&p.parser, &p.event) {
- p.fail()
- }
-}
-
-func (p *parser) fail() {
- var where string
- var line int
- if p.parser.problem_mark.line != 0 {
- line = p.parser.problem_mark.line
- } else if p.parser.context_mark.line != 0 {
- line = p.parser.context_mark.line
- }
- if line != 0 {
- where = "line " + strconv.Itoa(line) + ": "
- }
- var msg string
- if len(p.parser.problem) > 0 {
- msg = p.parser.problem
- } else {
- msg = "unknown problem parsing YAML content"
- }
- failf("%s%s", where, msg)
-}
-
-func (p *parser) anchor(n *node, anchor []byte) {
- if anchor != nil {
- p.doc.anchors[string(anchor)] = n
- }
-}
-
-func (p *parser) parse() *node {
- switch p.event.typ {
- case yaml_SCALAR_EVENT:
- return p.scalar()
- case yaml_ALIAS_EVENT:
- return p.alias()
- case yaml_MAPPING_START_EVENT:
- return p.mapping()
- case yaml_SEQUENCE_START_EVENT:
- return p.sequence()
- case yaml_DOCUMENT_START_EVENT:
- return p.document()
- case yaml_STREAM_END_EVENT:
- // Happens when attempting to decode an empty buffer.
- return nil
- default:
- panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
- }
- panic("unreachable")
-}
-
-func (p *parser) node(kind int) *node {
- return &node{
- kind: kind,
- line: p.event.start_mark.line,
- column: p.event.start_mark.column,
- }
-}
-
-func (p *parser) document() *node {
- n := p.node(documentNode)
- n.anchors = make(map[string]*node)
- p.doc = n
- p.skip()
- n.children = append(n.children, p.parse())
- if p.event.typ != yaml_DOCUMENT_END_EVENT {
- panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
- }
- p.skip()
- return n
-}
-
-func (p *parser) alias() *node {
- n := p.node(aliasNode)
- n.value = string(p.event.anchor)
- p.skip()
- return n
-}
-
-func (p *parser) scalar() *node {
- n := p.node(scalarNode)
- n.value = string(p.event.value)
- n.tag = string(p.event.tag)
- n.implicit = p.event.implicit
- p.anchor(n, p.event.anchor)
- p.skip()
- return n
-}
-
-func (p *parser) sequence() *node {
- n := p.node(sequenceNode)
- p.anchor(n, p.event.anchor)
- p.skip()
- for p.event.typ != yaml_SEQUENCE_END_EVENT {
- n.children = append(n.children, p.parse())
- }
- p.skip()
- return n
-}
-
-func (p *parser) mapping() *node {
- n := p.node(mappingNode)
- p.anchor(n, p.event.anchor)
- p.skip()
- for p.event.typ != yaml_MAPPING_END_EVENT {
- n.children = append(n.children, p.parse(), p.parse())
- }
- p.skip()
- return n
-}
-
-// ----------------------------------------------------------------------------
-// Decoder, unmarshals a node into a provided value.
-
-type decoder struct {
- doc *node
- aliases map[string]bool
- mapType reflect.Type
- terrors []string
-}
-
-var (
- mapItemType = reflect.TypeOf(MapItem{})
- durationType = reflect.TypeOf(time.Duration(0))
- defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
- ifaceType = defaultMapType.Elem()
-)
-
-func newDecoder() *decoder {
- d := &decoder{mapType: defaultMapType}
- d.aliases = make(map[string]bool)
- return d
-}
-
-func (d *decoder) terror(n *node, tag string, out reflect.Value) {
- if n.tag != "" {
- tag = n.tag
- }
- value := n.value
- if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
- if len(value) > 10 {
- value = " `" + value[:7] + "...`"
- } else {
- value = " `" + value + "`"
- }
- }
- d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
-}
-
-func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
- terrlen := len(d.terrors)
- err := u.UnmarshalYAML(func(v interface{}) (err error) {
- defer handleErr(&err)
- d.unmarshal(n, reflect.ValueOf(v))
- if len(d.terrors) > terrlen {
- issues := d.terrors[terrlen:]
- d.terrors = d.terrors[:terrlen]
- return &TypeError{issues}
- }
- return nil
- })
- if e, ok := err.(*TypeError); ok {
- d.terrors = append(d.terrors, e.Errors...)
- return false
- }
- if err != nil {
- fail(err)
- }
- return true
-}
-
-// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
-// if a value is found to implement it.
-// It returns the initialized and dereferenced out value, whether
-// unmarshalling was already done by UnmarshalYAML, and if so whether
-// its types unmarshalled appropriately.
-//
-// If n holds a null value, prepare returns before doing anything.
-func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
- if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
- return out, false, false
- }
- again := true
- for again {
- again = false
- if out.Kind() == reflect.Ptr {
- if out.IsNil() {
- out.Set(reflect.New(out.Type().Elem()))
- }
- out = out.Elem()
- again = true
- }
- if out.CanAddr() {
- if u, ok := out.Addr().Interface().(Unmarshaler); ok {
- good = d.callUnmarshaler(n, u)
- return out, true, good
- }
- }
- }
- return out, false, false
-}
-
-func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
- switch n.kind {
- case documentNode:
- return d.document(n, out)
- case aliasNode:
- return d.alias(n, out)
- }
- out, unmarshaled, good := d.prepare(n, out)
- if unmarshaled {
- return good
- }
- switch n.kind {
- case scalarNode:
- good = d.scalar(n, out)
- case mappingNode:
- good = d.mapping(n, out)
- case sequenceNode:
- good = d.sequence(n, out)
- default:
- panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
- }
- return good
-}
-
-func (d *decoder) document(n *node, out reflect.Value) (good bool) {
- if len(n.children) == 1 {
- d.doc = n
- d.unmarshal(n.children[0], out)
- return true
- }
- return false
-}
-
-func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
- an, ok := d.doc.anchors[n.value]
- if !ok {
- failf("unknown anchor '%s' referenced", n.value)
- }
- if d.aliases[n.value] {
- failf("anchor '%s' value contains itself", n.value)
- }
- d.aliases[n.value] = true
- good = d.unmarshal(an, out)
- delete(d.aliases, n.value)
- return good
-}
-
-var zeroValue reflect.Value
-
-func resetMap(out reflect.Value) {
- for _, k := range out.MapKeys() {
- out.SetMapIndex(k, zeroValue)
- }
-}
-
-func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
- var tag string
- var resolved interface{}
- if n.tag == "" && !n.implicit {
- tag = yaml_STR_TAG
- resolved = n.value
- } else {
- tag, resolved = resolve(n.tag, n.value)
- if tag == yaml_BINARY_TAG {
- data, err := base64.StdEncoding.DecodeString(resolved.(string))
- if err != nil {
- failf("!!binary value contains invalid base64 data")
- }
- resolved = string(data)
- }
- }
- if resolved == nil {
- if out.Kind() == reflect.Map && !out.CanAddr() {
- resetMap(out)
- } else {
- out.Set(reflect.Zero(out.Type()))
- }
- return true
- }
- if s, ok := resolved.(string); ok && out.CanAddr() {
- if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
- err := u.UnmarshalText([]byte(s))
- if err != nil {
- fail(err)
- }
- return true
- }
- }
- switch out.Kind() {
- case reflect.String:
- if tag == yaml_BINARY_TAG {
- out.SetString(resolved.(string))
- good = true
- } else if resolved != nil {
- out.SetString(n.value)
- good = true
- }
- case reflect.Interface:
- if resolved == nil {
- out.Set(reflect.Zero(out.Type()))
- } else {
- out.Set(reflect.ValueOf(resolved))
- }
- good = true
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- switch resolved := resolved.(type) {
- case int:
- if !out.OverflowInt(int64(resolved)) {
- out.SetInt(int64(resolved))
- good = true
- }
- case int64:
- if !out.OverflowInt(resolved) {
- out.SetInt(resolved)
- good = true
- }
- case uint64:
- if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
- out.SetInt(int64(resolved))
- good = true
- }
- case float64:
- if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
- out.SetInt(int64(resolved))
- good = true
- }
- case string:
- if out.Type() == durationType {
- d, err := time.ParseDuration(resolved)
- if err == nil {
- out.SetInt(int64(d))
- good = true
- }
- }
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- switch resolved := resolved.(type) {
- case int:
- if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
- out.SetUint(uint64(resolved))
- good = true
- }
- case int64:
- if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
- out.SetUint(uint64(resolved))
- good = true
- }
- case uint64:
- if !out.OverflowUint(uint64(resolved)) {
- out.SetUint(uint64(resolved))
- good = true
- }
- case float64:
- if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
- out.SetUint(uint64(resolved))
- good = true
- }
- }
- case reflect.Bool:
- switch resolved := resolved.(type) {
- case bool:
- out.SetBool(resolved)
- good = true
- }
- case reflect.Float32, reflect.Float64:
- switch resolved := resolved.(type) {
- case int:
- out.SetFloat(float64(resolved))
- good = true
- case int64:
- out.SetFloat(float64(resolved))
- good = true
- case uint64:
- out.SetFloat(float64(resolved))
- good = true
- case float64:
- out.SetFloat(resolved)
- good = true
- }
- case reflect.Ptr:
- if out.Type().Elem() == reflect.TypeOf(resolved) {
- // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
- elem := reflect.New(out.Type().Elem())
- elem.Elem().Set(reflect.ValueOf(resolved))
- out.Set(elem)
- good = true
- }
- }
- if !good {
- d.terror(n, tag, out)
- }
- return good
-}
-
-func settableValueOf(i interface{}) reflect.Value {
- v := reflect.ValueOf(i)
- sv := reflect.New(v.Type()).Elem()
- sv.Set(v)
- return sv
-}
-
-func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
- l := len(n.children)
-
- var iface reflect.Value
- switch out.Kind() {
- case reflect.Slice:
- out.Set(reflect.MakeSlice(out.Type(), l, l))
- case reflect.Interface:
- // No type hints. Will have to use a generic sequence.
- iface = out
- out = settableValueOf(make([]interface{}, l))
- default:
- d.terror(n, yaml_SEQ_TAG, out)
- return false
- }
- et := out.Type().Elem()
-
- j := 0
- for i := 0; i < l; i++ {
- e := reflect.New(et).Elem()
- if ok := d.unmarshal(n.children[i], e); ok {
- out.Index(j).Set(e)
- j++
- }
- }
- out.Set(out.Slice(0, j))
- if iface.IsValid() {
- iface.Set(out)
- }
- return true
-}
-
-func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
- switch out.Kind() {
- case reflect.Struct:
- return d.mappingStruct(n, out)
- case reflect.Slice:
- return d.mappingSlice(n, out)
- case reflect.Map:
- // okay
- case reflect.Interface:
- if d.mapType.Kind() == reflect.Map {
- iface := out
- out = reflect.MakeMap(d.mapType)
- iface.Set(out)
- } else {
- slicev := reflect.New(d.mapType).Elem()
- if !d.mappingSlice(n, slicev) {
- return false
- }
- out.Set(slicev)
- return true
- }
- default:
- d.terror(n, yaml_MAP_TAG, out)
- return false
- }
- outt := out.Type()
- kt := outt.Key()
- et := outt.Elem()
-
- mapType := d.mapType
- if outt.Key() == ifaceType && outt.Elem() == ifaceType {
- d.mapType = outt
- }
-
- if out.IsNil() {
- out.Set(reflect.MakeMap(outt))
- }
- l := len(n.children)
- for i := 0; i < l; i += 2 {
- if isMerge(n.children[i]) {
- d.merge(n.children[i+1], out)
- continue
- }
- k := reflect.New(kt).Elem()
- if d.unmarshal(n.children[i], k) {
- kkind := k.Kind()
- if kkind == reflect.Interface {
- kkind = k.Elem().Kind()
- }
- if kkind == reflect.Map || kkind == reflect.Slice {
- failf("invalid map key: %#v", k.Interface())
- }
- e := reflect.New(et).Elem()
- if d.unmarshal(n.children[i+1], e) {
- out.SetMapIndex(k, e)
- }
- }
- }
- d.mapType = mapType
- return true
-}
-
-func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
- outt := out.Type()
- if outt.Elem() != mapItemType {
- d.terror(n, yaml_MAP_TAG, out)
- return false
- }
-
- mapType := d.mapType
- d.mapType = outt
-
- var slice []MapItem
- var l = len(n.children)
- for i := 0; i < l; i += 2 {
- if isMerge(n.children[i]) {
- d.merge(n.children[i+1], out)
- continue
- }
- item := MapItem{}
- k := reflect.ValueOf(&item.Key).Elem()
- if d.unmarshal(n.children[i], k) {
- v := reflect.ValueOf(&item.Value).Elem()
- if d.unmarshal(n.children[i+1], v) {
- slice = append(slice, item)
- }
- }
- }
- out.Set(reflect.ValueOf(slice))
- d.mapType = mapType
- return true
-}
-
-func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
- sinfo, err := getStructInfo(out.Type())
- if err != nil {
- panic(err)
- }
- name := settableValueOf("")
- l := len(n.children)
-
- var inlineMap reflect.Value
- var elemType reflect.Type
- if sinfo.InlineMap != -1 {
- inlineMap = out.Field(sinfo.InlineMap)
- inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
- elemType = inlineMap.Type().Elem()
- }
-
- for i := 0; i < l; i += 2 {
- ni := n.children[i]
- if isMerge(ni) {
- d.merge(n.children[i+1], out)
- continue
- }
- if !d.unmarshal(ni, name) {
- continue
- }
- if info, ok := sinfo.FieldsMap[name.String()]; ok {
- var field reflect.Value
- if info.Inline == nil {
- field = out.Field(info.Num)
- } else {
- field = out.FieldByIndex(info.Inline)
- }
- d.unmarshal(n.children[i+1], field)
- } else if sinfo.InlineMap != -1 {
- if inlineMap.IsNil() {
- inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
- }
- value := reflect.New(elemType).Elem()
- d.unmarshal(n.children[i+1], value)
- inlineMap.SetMapIndex(name, value)
- }
- }
- return true
-}
-
-func failWantMap() {
- failf("map merge requires map or sequence of maps as the value")
-}
-
-func (d *decoder) merge(n *node, out reflect.Value) {
- switch n.kind {
- case mappingNode:
- d.unmarshal(n, out)
- case aliasNode:
- an, ok := d.doc.anchors[n.value]
- if ok && an.kind != mappingNode {
- failWantMap()
- }
- d.unmarshal(n, out)
- case sequenceNode:
- // Step backwards as earlier nodes take precedence.
- for i := len(n.children) - 1; i >= 0; i-- {
- ni := n.children[i]
- if ni.kind == aliasNode {
- an, ok := d.doc.anchors[ni.value]
- if ok && an.kind != mappingNode {
- failWantMap()
- }
- } else if ni.kind != mappingNode {
- failWantMap()
- }
- d.unmarshal(ni, out)
- }
- default:
- failWantMap()
- }
-}
-
-func isMerge(n *node) bool {
- return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/emitterc.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/emitterc.go
deleted file mode 100644
index 2befd553e..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/emitterc.go
+++ /dev/null
@@ -1,1685 +0,0 @@
-package yaml
-
-import (
- "bytes"
-)
-
-// Flush the buffer if needed.
-func flush(emitter *yaml_emitter_t) bool {
- if emitter.buffer_pos+5 >= len(emitter.buffer) {
- return yaml_emitter_flush(emitter)
- }
- return true
-}
-
-// Put a character to the output buffer.
-func put(emitter *yaml_emitter_t, value byte) bool {
- if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
- return false
- }
- emitter.buffer[emitter.buffer_pos] = value
- emitter.buffer_pos++
- emitter.column++
- return true
-}
-
-// Put a line break to the output buffer.
-func put_break(emitter *yaml_emitter_t) bool {
- if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
- return false
- }
- switch emitter.line_break {
- case yaml_CR_BREAK:
- emitter.buffer[emitter.buffer_pos] = '\r'
- emitter.buffer_pos += 1
- case yaml_LN_BREAK:
- emitter.buffer[emitter.buffer_pos] = '\n'
- emitter.buffer_pos += 1
- case yaml_CRLN_BREAK:
- emitter.buffer[emitter.buffer_pos+0] = '\r'
- emitter.buffer[emitter.buffer_pos+1] = '\n'
- emitter.buffer_pos += 2
- default:
- panic("unknown line break setting")
- }
- emitter.column = 0
- emitter.line++
- return true
-}
-
-// Copy a character from a string into buffer.
-func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
- if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
- return false
- }
- p := emitter.buffer_pos
- w := width(s[*i])
- switch w {
- case 4:
- emitter.buffer[p+3] = s[*i+3]
- fallthrough
- case 3:
- emitter.buffer[p+2] = s[*i+2]
- fallthrough
- case 2:
- emitter.buffer[p+1] = s[*i+1]
- fallthrough
- case 1:
- emitter.buffer[p+0] = s[*i+0]
- default:
- panic("unknown character width")
- }
- emitter.column++
- emitter.buffer_pos += w
- *i += w
- return true
-}
-
-// Write a whole string into buffer.
-func write_all(emitter *yaml_emitter_t, s []byte) bool {
- for i := 0; i < len(s); {
- if !write(emitter, s, &i) {
- return false
- }
- }
- return true
-}
-
-// Copy a line break character from a string into buffer.
-func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
- if s[*i] == '\n' {
- if !put_break(emitter) {
- return false
- }
- *i++
- } else {
- if !write(emitter, s, i) {
- return false
- }
- emitter.column = 0
- emitter.line++
- }
- return true
-}
-
-// Set an emitter error and return false.
-func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
- emitter.error = yaml_EMITTER_ERROR
- emitter.problem = problem
- return false
-}
-
-// Emit an event.
-func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- emitter.events = append(emitter.events, *event)
- for !yaml_emitter_need_more_events(emitter) {
- event := &emitter.events[emitter.events_head]
- if !yaml_emitter_analyze_event(emitter, event) {
- return false
- }
- if !yaml_emitter_state_machine(emitter, event) {
- return false
- }
- yaml_event_delete(event)
- emitter.events_head++
- }
- return true
-}
-
-// Check if we need to accumulate more events before emitting.
-//
-// We accumulate extra
-// - 1 event for DOCUMENT-START
-// - 2 events for SEQUENCE-START
-// - 3 events for MAPPING-START
-//
-func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
- if emitter.events_head == len(emitter.events) {
- return true
- }
- var accumulate int
- switch emitter.events[emitter.events_head].typ {
- case yaml_DOCUMENT_START_EVENT:
- accumulate = 1
- break
- case yaml_SEQUENCE_START_EVENT:
- accumulate = 2
- break
- case yaml_MAPPING_START_EVENT:
- accumulate = 3
- break
- default:
- return false
- }
- if len(emitter.events)-emitter.events_head > accumulate {
- return false
- }
- var level int
- for i := emitter.events_head; i < len(emitter.events); i++ {
- switch emitter.events[i].typ {
- case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
- level++
- case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
- level--
- }
- if level == 0 {
- return false
- }
- }
- return true
-}
-
-// Append a directive to the directives stack.
-func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
- for i := 0; i < len(emitter.tag_directives); i++ {
- if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
- if allow_duplicates {
- return true
- }
- return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
- }
- }
-
- // [Go] Do we actually need to copy this given garbage collection
- // and the lack of deallocating destructors?
- tag_copy := yaml_tag_directive_t{
- handle: make([]byte, len(value.handle)),
- prefix: make([]byte, len(value.prefix)),
- }
- copy(tag_copy.handle, value.handle)
- copy(tag_copy.prefix, value.prefix)
- emitter.tag_directives = append(emitter.tag_directives, tag_copy)
- return true
-}
-
-// Increase the indentation level.
-func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
- emitter.indents = append(emitter.indents, emitter.indent)
- if emitter.indent < 0 {
- if flow {
- emitter.indent = emitter.best_indent
- } else {
- emitter.indent = 0
- }
- } else if !indentless {
- emitter.indent += emitter.best_indent
- }
- return true
-}
-
-// State dispatcher.
-func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- switch emitter.state {
- default:
- case yaml_EMIT_STREAM_START_STATE:
- return yaml_emitter_emit_stream_start(emitter, event)
-
- case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
- return yaml_emitter_emit_document_start(emitter, event, true)
-
- case yaml_EMIT_DOCUMENT_START_STATE:
- return yaml_emitter_emit_document_start(emitter, event, false)
-
- case yaml_EMIT_DOCUMENT_CONTENT_STATE:
- return yaml_emitter_emit_document_content(emitter, event)
-
- case yaml_EMIT_DOCUMENT_END_STATE:
- return yaml_emitter_emit_document_end(emitter, event)
-
- case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
- return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
-
- case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
- return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
-
- case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
- return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
-
- case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
- return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
-
- case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
- return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
-
- case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
- return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
-
- case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
- return yaml_emitter_emit_block_sequence_item(emitter, event, true)
-
- case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
- return yaml_emitter_emit_block_sequence_item(emitter, event, false)
-
- case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
- return yaml_emitter_emit_block_mapping_key(emitter, event, true)
-
- case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
- return yaml_emitter_emit_block_mapping_key(emitter, event, false)
-
- case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
- return yaml_emitter_emit_block_mapping_value(emitter, event, true)
-
- case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
- return yaml_emitter_emit_block_mapping_value(emitter, event, false)
-
- case yaml_EMIT_END_STATE:
- return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
- }
- panic("invalid emitter state")
-}
-
-// Expect STREAM-START.
-func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if event.typ != yaml_STREAM_START_EVENT {
- return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
- }
- if emitter.encoding == yaml_ANY_ENCODING {
- emitter.encoding = event.encoding
- if emitter.encoding == yaml_ANY_ENCODING {
- emitter.encoding = yaml_UTF8_ENCODING
- }
- }
- if emitter.best_indent < 2 || emitter.best_indent > 9 {
- emitter.best_indent = 2
- }
- if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
- emitter.best_width = 80
- }
- if emitter.best_width < 0 {
- emitter.best_width = 1<<31 - 1
- }
- if emitter.line_break == yaml_ANY_BREAK {
- emitter.line_break = yaml_LN_BREAK
- }
-
- emitter.indent = -1
- emitter.line = 0
- emitter.column = 0
- emitter.whitespace = true
- emitter.indention = true
-
- if emitter.encoding != yaml_UTF8_ENCODING {
- if !yaml_emitter_write_bom(emitter) {
- return false
- }
- }
- emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
- return true
-}
-
-// Expect DOCUMENT-START or STREAM-END.
-func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-
- if event.typ == yaml_DOCUMENT_START_EVENT {
-
- if event.version_directive != nil {
- if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
- return false
- }
- }
-
- for i := 0; i < len(event.tag_directives); i++ {
- tag_directive := &event.tag_directives[i]
- if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
- return false
- }
- if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
- return false
- }
- }
-
- for i := 0; i < len(default_tag_directives); i++ {
- tag_directive := &default_tag_directives[i]
- if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
- return false
- }
- }
-
- implicit := event.implicit
- if !first || emitter.canonical {
- implicit = false
- }
-
- if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
- if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
-
- if event.version_directive != nil {
- implicit = false
- if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
- return false
- }
- if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
-
- if len(event.tag_directives) > 0 {
- implicit = false
- for i := 0; i < len(event.tag_directives); i++ {
- tag_directive := &event.tag_directives[i]
- if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
- return false
- }
- if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
- return false
- }
- if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- }
-
- if yaml_emitter_check_empty_document(emitter) {
- implicit = false
- }
- if !implicit {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
- return false
- }
- if emitter.canonical {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- }
-
- emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
- return true
- }
-
- if event.typ == yaml_STREAM_END_EVENT {
- if emitter.open_ended {
- if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !yaml_emitter_flush(emitter) {
- return false
- }
- emitter.state = yaml_EMIT_END_STATE
- return true
- }
-
- return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
-}
-
-// Expect the root node.
-func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
- return yaml_emitter_emit_node(emitter, event, true, false, false, false)
-}
-
-// Expect DOCUMENT-END.
-func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if event.typ != yaml_DOCUMENT_END_EVENT {
- return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if !event.implicit {
- // [Go] Allocate the slice elsewhere.
- if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !yaml_emitter_flush(emitter) {
- return false
- }
- emitter.state = yaml_EMIT_DOCUMENT_START_STATE
- emitter.tag_directives = emitter.tag_directives[:0]
- return true
-}
-
-// Expect a flow item node.
-func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
- if first {
- if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
- return false
- }
- if !yaml_emitter_increase_indent(emitter, true, false) {
- return false
- }
- emitter.flow_level++
- }
-
- if event.typ == yaml_SEQUENCE_END_EVENT {
- emitter.flow_level--
- emitter.indent = emitter.indents[len(emitter.indents)-1]
- emitter.indents = emitter.indents[:len(emitter.indents)-1]
- if emitter.canonical && !first {
- if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
- return false
- }
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
-
- return true
- }
-
- if !first {
- if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
- return false
- }
- }
-
- if emitter.canonical || emitter.column > emitter.best_width {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
- return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a flow key node.
-func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
- if first {
- if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
- return false
- }
- if !yaml_emitter_increase_indent(emitter, true, false) {
- return false
- }
- emitter.flow_level++
- }
-
- if event.typ == yaml_MAPPING_END_EVENT {
- emitter.flow_level--
- emitter.indent = emitter.indents[len(emitter.indents)-1]
- emitter.indents = emitter.indents[:len(emitter.indents)-1]
- if emitter.canonical && !first {
- if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
- return false
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
- return false
- }
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
- return true
- }
-
- if !first {
- if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
- return false
- }
- }
- if emitter.canonical || emitter.column > emitter.best_width {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
-
- if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
- emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, true)
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
- return false
- }
- emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a flow value node.
-func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
- if simple {
- if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
- return false
- }
- } else {
- if emitter.canonical || emitter.column > emitter.best_width {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
- return false
- }
- }
- emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block item node.
-func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
- if first {
- if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
- return false
- }
- }
- if event.typ == yaml_SEQUENCE_END_EVENT {
- emitter.indent = emitter.indents[len(emitter.indents)-1]
- emitter.indents = emitter.indents[:len(emitter.indents)-1]
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
- return true
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
- return false
- }
- emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
- return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a block key node.
-func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
- if first {
- if !yaml_emitter_increase_indent(emitter, false, false) {
- return false
- }
- }
- if event.typ == yaml_MAPPING_END_EVENT {
- emitter.indent = emitter.indents[len(emitter.indents)-1]
- emitter.indents = emitter.indents[:len(emitter.indents)-1]
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
- return true
- }
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if yaml_emitter_check_simple_key(emitter) {
- emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, true)
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
- return false
- }
- emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block value node.
-func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
- if simple {
- if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
- return false
- }
- } else {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
- return false
- }
- }
- emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
- return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a node.
-func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
- root bool, sequence bool, mapping bool, simple_key bool) bool {
-
- emitter.root_context = root
- emitter.sequence_context = sequence
- emitter.mapping_context = mapping
- emitter.simple_key_context = simple_key
-
- switch event.typ {
- case yaml_ALIAS_EVENT:
- return yaml_emitter_emit_alias(emitter, event)
- case yaml_SCALAR_EVENT:
- return yaml_emitter_emit_scalar(emitter, event)
- case yaml_SEQUENCE_START_EVENT:
- return yaml_emitter_emit_sequence_start(emitter, event)
- case yaml_MAPPING_START_EVENT:
- return yaml_emitter_emit_mapping_start(emitter, event)
- default:
- return yaml_emitter_set_emitter_error(emitter,
- "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
- }
- return false
-}
-
-// Expect ALIAS.
-func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if !yaml_emitter_process_anchor(emitter) {
- return false
- }
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
- return true
-}
-
-// Expect SCALAR.
-func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if !yaml_emitter_select_scalar_style(emitter, event) {
- return false
- }
- if !yaml_emitter_process_anchor(emitter) {
- return false
- }
- if !yaml_emitter_process_tag(emitter) {
- return false
- }
- if !yaml_emitter_increase_indent(emitter, true, false) {
- return false
- }
- if !yaml_emitter_process_scalar(emitter) {
- return false
- }
- emitter.indent = emitter.indents[len(emitter.indents)-1]
- emitter.indents = emitter.indents[:len(emitter.indents)-1]
- emitter.state = emitter.states[len(emitter.states)-1]
- emitter.states = emitter.states[:len(emitter.states)-1]
- return true
-}
-
-// Expect SEQUENCE-START.
-func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if !yaml_emitter_process_anchor(emitter) {
- return false
- }
- if !yaml_emitter_process_tag(emitter) {
- return false
- }
- if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
- yaml_emitter_check_empty_sequence(emitter) {
- emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
- } else {
- emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
- }
- return true
-}
-
-// Expect MAPPING-START.
-func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
- if !yaml_emitter_process_anchor(emitter) {
- return false
- }
- if !yaml_emitter_process_tag(emitter) {
- return false
- }
- if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
- yaml_emitter_check_empty_mapping(emitter) {
- emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
- } else {
- emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
- }
- return true
-}
-
-// Check if the document content is an empty scalar.
-func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
- return false // [Go] Huh?
-}
-
-// Check if the next events represent an empty sequence.
-func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
- if len(emitter.events)-emitter.events_head < 2 {
- return false
- }
- return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
- emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
-}
-
-// Check if the next events represent an empty mapping.
-func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
- if len(emitter.events)-emitter.events_head < 2 {
- return false
- }
- return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
- emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
-}
-
-// Check if the next node can be expressed as a simple key.
-func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
- length := 0
- switch emitter.events[emitter.events_head].typ {
- case yaml_ALIAS_EVENT:
- length += len(emitter.anchor_data.anchor)
- case yaml_SCALAR_EVENT:
- if emitter.scalar_data.multiline {
- return false
- }
- length += len(emitter.anchor_data.anchor) +
- len(emitter.tag_data.handle) +
- len(emitter.tag_data.suffix) +
- len(emitter.scalar_data.value)
- case yaml_SEQUENCE_START_EVENT:
- if !yaml_emitter_check_empty_sequence(emitter) {
- return false
- }
- length += len(emitter.anchor_data.anchor) +
- len(emitter.tag_data.handle) +
- len(emitter.tag_data.suffix)
- case yaml_MAPPING_START_EVENT:
- if !yaml_emitter_check_empty_mapping(emitter) {
- return false
- }
- length += len(emitter.anchor_data.anchor) +
- len(emitter.tag_data.handle) +
- len(emitter.tag_data.suffix)
- default:
- return false
- }
- return length <= 128
-}
-
-// Determine an acceptable scalar style.
-func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
- no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
- if no_tag && !event.implicit && !event.quoted_implicit {
- return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
- }
-
- style := event.scalar_style()
- if style == yaml_ANY_SCALAR_STYLE {
- style = yaml_PLAIN_SCALAR_STYLE
- }
- if emitter.canonical {
- style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- }
- if emitter.simple_key_context && emitter.scalar_data.multiline {
- style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- }
-
- if style == yaml_PLAIN_SCALAR_STYLE {
- if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
- emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
- style = yaml_SINGLE_QUOTED_SCALAR_STYLE
- }
- if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
- style = yaml_SINGLE_QUOTED_SCALAR_STYLE
- }
- if no_tag && !event.implicit {
- style = yaml_SINGLE_QUOTED_SCALAR_STYLE
- }
- }
- if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
- if !emitter.scalar_data.single_quoted_allowed {
- style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- }
- }
- if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
- if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
- style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- }
- }
-
- if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
- emitter.tag_data.handle = []byte{'!'}
- }
- emitter.scalar_data.style = style
- return true
-}
-
-// Write an achor.
-func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
- if emitter.anchor_data.anchor == nil {
- return true
- }
- c := []byte{'&'}
- if emitter.anchor_data.alias {
- c[0] = '*'
- }
- if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
- return false
- }
- return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
-}
-
-// Write a tag.
-func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
- if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
- return true
- }
- if len(emitter.tag_data.handle) > 0 {
- if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
- return false
- }
- if len(emitter.tag_data.suffix) > 0 {
- if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
- return false
- }
- }
- } else {
- // [Go] Allocate these slices elsewhere.
- if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
- return false
- }
- if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
- return false
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
- return false
- }
- }
- return true
-}
-
-// Write a scalar.
-func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
- switch emitter.scalar_data.style {
- case yaml_PLAIN_SCALAR_STYLE:
- return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
- case yaml_SINGLE_QUOTED_SCALAR_STYLE:
- return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
- case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
- return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
- case yaml_LITERAL_SCALAR_STYLE:
- return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
-
- case yaml_FOLDED_SCALAR_STYLE:
- return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
- }
- panic("unknown scalar style")
-}
-
-// Check if a %YAML directive is valid.
-func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
- if version_directive.major != 1 || version_directive.minor != 1 {
- return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
- }
- return true
-}
-
-// Check if a %TAG directive is valid.
-func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
- handle := tag_directive.handle
- prefix := tag_directive.prefix
- if len(handle) == 0 {
- return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
- }
- if handle[0] != '!' {
- return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
- }
- if handle[len(handle)-1] != '!' {
- return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
- }
- for i := 1; i < len(handle)-1; i += width(handle[i]) {
- if !is_alpha(handle, i) {
- return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
- }
- }
- if len(prefix) == 0 {
- return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
- }
- return true
-}
-
-// Check if an anchor is valid.
-func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
- if len(anchor) == 0 {
- problem := "anchor value must not be empty"
- if alias {
- problem = "alias value must not be empty"
- }
- return yaml_emitter_set_emitter_error(emitter, problem)
- }
- for i := 0; i < len(anchor); i += width(anchor[i]) {
- if !is_alpha(anchor, i) {
- problem := "anchor value must contain alphanumerical characters only"
- if alias {
- problem = "alias value must contain alphanumerical characters only"
- }
- return yaml_emitter_set_emitter_error(emitter, problem)
- }
- }
- emitter.anchor_data.anchor = anchor
- emitter.anchor_data.alias = alias
- return true
-}
-
-// Check if a tag is valid.
-func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
- if len(tag) == 0 {
- return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
- }
- for i := 0; i < len(emitter.tag_directives); i++ {
- tag_directive := &emitter.tag_directives[i]
- if bytes.HasPrefix(tag, tag_directive.prefix) {
- emitter.tag_data.handle = tag_directive.handle
- emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
- return true
- }
- }
- emitter.tag_data.suffix = tag
- return true
-}
-
-// Check if a scalar is valid.
-func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
- var (
- block_indicators = false
- flow_indicators = false
- line_breaks = false
- special_characters = false
-
- leading_space = false
- leading_break = false
- trailing_space = false
- trailing_break = false
- break_space = false
- space_break = false
-
- preceeded_by_whitespace = false
- followed_by_whitespace = false
- previous_space = false
- previous_break = false
- )
-
- emitter.scalar_data.value = value
-
- if len(value) == 0 {
- emitter.scalar_data.multiline = false
- emitter.scalar_data.flow_plain_allowed = false
- emitter.scalar_data.block_plain_allowed = true
- emitter.scalar_data.single_quoted_allowed = true
- emitter.scalar_data.block_allowed = false
- return true
- }
-
- if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
- block_indicators = true
- flow_indicators = true
- }
-
- preceeded_by_whitespace = true
- for i, w := 0, 0; i < len(value); i += w {
- w = width(value[i])
- followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
-
- if i == 0 {
- switch value[i] {
- case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
- flow_indicators = true
- block_indicators = true
- case '?', ':':
- flow_indicators = true
- if followed_by_whitespace {
- block_indicators = true
- }
- case '-':
- if followed_by_whitespace {
- flow_indicators = true
- block_indicators = true
- }
- }
- } else {
- switch value[i] {
- case ',', '?', '[', ']', '{', '}':
- flow_indicators = true
- case ':':
- flow_indicators = true
- if followed_by_whitespace {
- block_indicators = true
- }
- case '#':
- if preceeded_by_whitespace {
- flow_indicators = true
- block_indicators = true
- }
- }
- }
-
- if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
- special_characters = true
- }
- if is_space(value, i) {
- if i == 0 {
- leading_space = true
- }
- if i+width(value[i]) == len(value) {
- trailing_space = true
- }
- if previous_break {
- break_space = true
- }
- previous_space = true
- previous_break = false
- } else if is_break(value, i) {
- line_breaks = true
- if i == 0 {
- leading_break = true
- }
- if i+width(value[i]) == len(value) {
- trailing_break = true
- }
- if previous_space {
- space_break = true
- }
- previous_space = false
- previous_break = true
- } else {
- previous_space = false
- previous_break = false
- }
-
- // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
- preceeded_by_whitespace = is_blankz(value, i)
- }
-
- emitter.scalar_data.multiline = line_breaks
- emitter.scalar_data.flow_plain_allowed = true
- emitter.scalar_data.block_plain_allowed = true
- emitter.scalar_data.single_quoted_allowed = true
- emitter.scalar_data.block_allowed = true
-
- if leading_space || leading_break || trailing_space || trailing_break {
- emitter.scalar_data.flow_plain_allowed = false
- emitter.scalar_data.block_plain_allowed = false
- }
- if trailing_space {
- emitter.scalar_data.block_allowed = false
- }
- if break_space {
- emitter.scalar_data.flow_plain_allowed = false
- emitter.scalar_data.block_plain_allowed = false
- emitter.scalar_data.single_quoted_allowed = false
- }
- if space_break || special_characters {
- emitter.scalar_data.flow_plain_allowed = false
- emitter.scalar_data.block_plain_allowed = false
- emitter.scalar_data.single_quoted_allowed = false
- emitter.scalar_data.block_allowed = false
- }
- if line_breaks {
- emitter.scalar_data.flow_plain_allowed = false
- emitter.scalar_data.block_plain_allowed = false
- }
- if flow_indicators {
- emitter.scalar_data.flow_plain_allowed = false
- }
- if block_indicators {
- emitter.scalar_data.block_plain_allowed = false
- }
- return true
-}
-
-// Check if the event data is valid.
-func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
- emitter.anchor_data.anchor = nil
- emitter.tag_data.handle = nil
- emitter.tag_data.suffix = nil
- emitter.scalar_data.value = nil
-
- switch event.typ {
- case yaml_ALIAS_EVENT:
- if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
- return false
- }
-
- case yaml_SCALAR_EVENT:
- if len(event.anchor) > 0 {
- if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
- return false
- }
- }
- if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
- if !yaml_emitter_analyze_tag(emitter, event.tag) {
- return false
- }
- }
- if !yaml_emitter_analyze_scalar(emitter, event.value) {
- return false
- }
-
- case yaml_SEQUENCE_START_EVENT:
- if len(event.anchor) > 0 {
- if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
- return false
- }
- }
- if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
- if !yaml_emitter_analyze_tag(emitter, event.tag) {
- return false
- }
- }
-
- case yaml_MAPPING_START_EVENT:
- if len(event.anchor) > 0 {
- if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
- return false
- }
- }
- if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
- if !yaml_emitter_analyze_tag(emitter, event.tag) {
- return false
- }
- }
- }
- return true
-}
-
-// Write the BOM character.
-func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
- if !flush(emitter) {
- return false
- }
- pos := emitter.buffer_pos
- emitter.buffer[pos+0] = '\xEF'
- emitter.buffer[pos+1] = '\xBB'
- emitter.buffer[pos+2] = '\xBF'
- emitter.buffer_pos += 3
- return true
-}
-
-func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
- indent := emitter.indent
- if indent < 0 {
- indent = 0
- }
- if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
- if !put_break(emitter) {
- return false
- }
- }
- for emitter.column < indent {
- if !put(emitter, ' ') {
- return false
- }
- }
- emitter.whitespace = true
- emitter.indention = true
- return true
-}
-
-func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
- if need_whitespace && !emitter.whitespace {
- if !put(emitter, ' ') {
- return false
- }
- }
- if !write_all(emitter, indicator) {
- return false
- }
- emitter.whitespace = is_whitespace
- emitter.indention = (emitter.indention && is_indention)
- emitter.open_ended = false
- return true
-}
-
-func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
- if !write_all(emitter, value) {
- return false
- }
- emitter.whitespace = false
- emitter.indention = false
- return true
-}
-
-func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
- if !emitter.whitespace {
- if !put(emitter, ' ') {
- return false
- }
- }
- if !write_all(emitter, value) {
- return false
- }
- emitter.whitespace = false
- emitter.indention = false
- return true
-}
-
-func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
- if need_whitespace && !emitter.whitespace {
- if !put(emitter, ' ') {
- return false
- }
- }
- for i := 0; i < len(value); {
- var must_write bool
- switch value[i] {
- case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
- must_write = true
- default:
- must_write = is_alpha(value, i)
- }
- if must_write {
- if !write(emitter, value, &i) {
- return false
- }
- } else {
- w := width(value[i])
- for k := 0; k < w; k++ {
- octet := value[i]
- i++
- if !put(emitter, '%') {
- return false
- }
-
- c := octet >> 4
- if c < 10 {
- c += '0'
- } else {
- c += 'A' - 10
- }
- if !put(emitter, c) {
- return false
- }
-
- c = octet & 0x0f
- if c < 10 {
- c += '0'
- } else {
- c += 'A' - 10
- }
- if !put(emitter, c) {
- return false
- }
- }
- }
- }
- emitter.whitespace = false
- emitter.indention = false
- return true
-}
-
-func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
- if !emitter.whitespace {
- if !put(emitter, ' ') {
- return false
- }
- }
-
- spaces := false
- breaks := false
- for i := 0; i < len(value); {
- if is_space(value, i) {
- if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- i += width(value[i])
- } else {
- if !write(emitter, value, &i) {
- return false
- }
- }
- spaces = true
- } else if is_break(value, i) {
- if !breaks && value[i] == '\n' {
- if !put_break(emitter) {
- return false
- }
- }
- if !write_break(emitter, value, &i) {
- return false
- }
- emitter.indention = true
- breaks = true
- } else {
- if breaks {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !write(emitter, value, &i) {
- return false
- }
- emitter.indention = false
- spaces = false
- breaks = false
- }
- }
-
- emitter.whitespace = false
- emitter.indention = false
- if emitter.root_context {
- emitter.open_ended = true
- }
-
- return true
-}
-
-func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-
- if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
- return false
- }
-
- spaces := false
- breaks := false
- for i := 0; i < len(value); {
- if is_space(value, i) {
- if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- i += width(value[i])
- } else {
- if !write(emitter, value, &i) {
- return false
- }
- }
- spaces = true
- } else if is_break(value, i) {
- if !breaks && value[i] == '\n' {
- if !put_break(emitter) {
- return false
- }
- }
- if !write_break(emitter, value, &i) {
- return false
- }
- emitter.indention = true
- breaks = true
- } else {
- if breaks {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if value[i] == '\'' {
- if !put(emitter, '\'') {
- return false
- }
- }
- if !write(emitter, value, &i) {
- return false
- }
- emitter.indention = false
- spaces = false
- breaks = false
- }
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
- return false
- }
- emitter.whitespace = false
- emitter.indention = false
- return true
-}
-
-func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
- spaces := false
- if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
- return false
- }
-
- for i := 0; i < len(value); {
- if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
- is_bom(value, i) || is_break(value, i) ||
- value[i] == '"' || value[i] == '\\' {
-
- octet := value[i]
-
- var w int
- var v rune
- switch {
- case octet&0x80 == 0x00:
- w, v = 1, rune(octet&0x7F)
- case octet&0xE0 == 0xC0:
- w, v = 2, rune(octet&0x1F)
- case octet&0xF0 == 0xE0:
- w, v = 3, rune(octet&0x0F)
- case octet&0xF8 == 0xF0:
- w, v = 4, rune(octet&0x07)
- }
- for k := 1; k < w; k++ {
- octet = value[i+k]
- v = (v << 6) + (rune(octet) & 0x3F)
- }
- i += w
-
- if !put(emitter, '\\') {
- return false
- }
-
- var ok bool
- switch v {
- case 0x00:
- ok = put(emitter, '0')
- case 0x07:
- ok = put(emitter, 'a')
- case 0x08:
- ok = put(emitter, 'b')
- case 0x09:
- ok = put(emitter, 't')
- case 0x0A:
- ok = put(emitter, 'n')
- case 0x0b:
- ok = put(emitter, 'v')
- case 0x0c:
- ok = put(emitter, 'f')
- case 0x0d:
- ok = put(emitter, 'r')
- case 0x1b:
- ok = put(emitter, 'e')
- case 0x22:
- ok = put(emitter, '"')
- case 0x5c:
- ok = put(emitter, '\\')
- case 0x85:
- ok = put(emitter, 'N')
- case 0xA0:
- ok = put(emitter, '_')
- case 0x2028:
- ok = put(emitter, 'L')
- case 0x2029:
- ok = put(emitter, 'P')
- default:
- if v <= 0xFF {
- ok = put(emitter, 'x')
- w = 2
- } else if v <= 0xFFFF {
- ok = put(emitter, 'u')
- w = 4
- } else {
- ok = put(emitter, 'U')
- w = 8
- }
- for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
- digit := byte((v >> uint(k)) & 0x0F)
- if digit < 10 {
- ok = put(emitter, digit+'0')
- } else {
- ok = put(emitter, digit+'A'-10)
- }
- }
- }
- if !ok {
- return false
- }
- spaces = false
- } else if is_space(value, i) {
- if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- if is_space(value, i+1) {
- if !put(emitter, '\\') {
- return false
- }
- }
- i += width(value[i])
- } else if !write(emitter, value, &i) {
- return false
- }
- spaces = true
- } else {
- if !write(emitter, value, &i) {
- return false
- }
- spaces = false
- }
- }
- if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
- return false
- }
- emitter.whitespace = false
- emitter.indention = false
- return true
-}
-
-func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
- if is_space(value, 0) || is_break(value, 0) {
- indent_hint := []byte{'0' + byte(emitter.best_indent)}
- if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
- return false
- }
- }
-
- emitter.open_ended = false
-
- var chomp_hint [1]byte
- if len(value) == 0 {
- chomp_hint[0] = '-'
- } else {
- i := len(value) - 1
- for value[i]&0xC0 == 0x80 {
- i--
- }
- if !is_break(value, i) {
- chomp_hint[0] = '-'
- } else if i == 0 {
- chomp_hint[0] = '+'
- emitter.open_ended = true
- } else {
- i--
- for value[i]&0xC0 == 0x80 {
- i--
- }
- if is_break(value, i) {
- chomp_hint[0] = '+'
- emitter.open_ended = true
- }
- }
- }
- if chomp_hint[0] != 0 {
- if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
- return false
- }
- }
- return true
-}
-
-func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
- if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
- return false
- }
- if !yaml_emitter_write_block_scalar_hints(emitter, value) {
- return false
- }
- if !put_break(emitter) {
- return false
- }
- emitter.indention = true
- emitter.whitespace = true
- breaks := true
- for i := 0; i < len(value); {
- if is_break(value, i) {
- if !write_break(emitter, value, &i) {
- return false
- }
- emitter.indention = true
- breaks = true
- } else {
- if breaks {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- }
- if !write(emitter, value, &i) {
- return false
- }
- emitter.indention = false
- breaks = false
- }
- }
-
- return true
-}
-
-func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
- if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
- return false
- }
- if !yaml_emitter_write_block_scalar_hints(emitter, value) {
- return false
- }
-
- if !put_break(emitter) {
- return false
- }
- emitter.indention = true
- emitter.whitespace = true
-
- breaks := true
- leading_spaces := true
- for i := 0; i < len(value); {
- if is_break(value, i) {
- if !breaks && !leading_spaces && value[i] == '\n' {
- k := 0
- for is_break(value, k) {
- k += width(value[k])
- }
- if !is_blankz(value, k) {
- if !put_break(emitter) {
- return false
- }
- }
- }
- if !write_break(emitter, value, &i) {
- return false
- }
- emitter.indention = true
- breaks = true
- } else {
- if breaks {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- leading_spaces = is_blank(value, i)
- }
- if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
- if !yaml_emitter_write_indent(emitter) {
- return false
- }
- i += width(value[i])
- } else {
- if !write(emitter, value, &i) {
- return false
- }
- }
- emitter.indention = false
- breaks = false
- }
- }
- return true
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/encode.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/encode.go
deleted file mode 100644
index 84f849955..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/encode.go
+++ /dev/null
@@ -1,306 +0,0 @@
-package yaml
-
-import (
- "encoding"
- "fmt"
- "reflect"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "time"
-)
-
-type encoder struct {
- emitter yaml_emitter_t
- event yaml_event_t
- out []byte
- flow bool
-}
-
-func newEncoder() (e *encoder) {
- e = &encoder{}
- e.must(yaml_emitter_initialize(&e.emitter))
- yaml_emitter_set_output_string(&e.emitter, &e.out)
- yaml_emitter_set_unicode(&e.emitter, true)
- e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
- e.emit()
- e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
- e.emit()
- return e
-}
-
-func (e *encoder) finish() {
- e.must(yaml_document_end_event_initialize(&e.event, true))
- e.emit()
- e.emitter.open_ended = false
- e.must(yaml_stream_end_event_initialize(&e.event))
- e.emit()
-}
-
-func (e *encoder) destroy() {
- yaml_emitter_delete(&e.emitter)
-}
-
-func (e *encoder) emit() {
- // This will internally delete the e.event value.
- if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
- e.must(false)
- }
-}
-
-func (e *encoder) must(ok bool) {
- if !ok {
- msg := e.emitter.problem
- if msg == "" {
- msg = "unknown problem generating YAML content"
- }
- failf("%s", msg)
- }
-}
-
-func (e *encoder) marshal(tag string, in reflect.Value) {
- if !in.IsValid() {
- e.nilv()
- return
- }
- iface := in.Interface()
- if m, ok := iface.(Marshaler); ok {
- v, err := m.MarshalYAML()
- if err != nil {
- fail(err)
- }
- if v == nil {
- e.nilv()
- return
- }
- in = reflect.ValueOf(v)
- } else if m, ok := iface.(encoding.TextMarshaler); ok {
- text, err := m.MarshalText()
- if err != nil {
- fail(err)
- }
- in = reflect.ValueOf(string(text))
- }
- switch in.Kind() {
- case reflect.Interface:
- if in.IsNil() {
- e.nilv()
- } else {
- e.marshal(tag, in.Elem())
- }
- case reflect.Map:
- e.mapv(tag, in)
- case reflect.Ptr:
- if in.IsNil() {
- e.nilv()
- } else {
- e.marshal(tag, in.Elem())
- }
- case reflect.Struct:
- e.structv(tag, in)
- case reflect.Slice:
- if in.Type().Elem() == mapItemType {
- e.itemsv(tag, in)
- } else {
- e.slicev(tag, in)
- }
- case reflect.String:
- e.stringv(tag, in)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if in.Type() == durationType {
- e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
- } else {
- e.intv(tag, in)
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- e.uintv(tag, in)
- case reflect.Float32, reflect.Float64:
- e.floatv(tag, in)
- case reflect.Bool:
- e.boolv(tag, in)
- default:
- panic("cannot marshal type: " + in.Type().String())
- }
-}
-
-func (e *encoder) mapv(tag string, in reflect.Value) {
- e.mappingv(tag, func() {
- keys := keyList(in.MapKeys())
- sort.Sort(keys)
- for _, k := range keys {
- e.marshal("", k)
- e.marshal("", in.MapIndex(k))
- }
- })
-}
-
-func (e *encoder) itemsv(tag string, in reflect.Value) {
- e.mappingv(tag, func() {
- slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
- for _, item := range slice {
- e.marshal("", reflect.ValueOf(item.Key))
- e.marshal("", reflect.ValueOf(item.Value))
- }
- })
-}
-
-func (e *encoder) structv(tag string, in reflect.Value) {
- sinfo, err := getStructInfo(in.Type())
- if err != nil {
- panic(err)
- }
- e.mappingv(tag, func() {
- for _, info := range sinfo.FieldsList {
- var value reflect.Value
- if info.Inline == nil {
- value = in.Field(info.Num)
- } else {
- value = in.FieldByIndex(info.Inline)
- }
- if info.OmitEmpty && isZero(value) {
- continue
- }
- e.marshal("", reflect.ValueOf(info.Key))
- e.flow = info.Flow
- e.marshal("", value)
- }
- if sinfo.InlineMap >= 0 {
- m := in.Field(sinfo.InlineMap)
- if m.Len() > 0 {
- e.flow = false
- keys := keyList(m.MapKeys())
- sort.Sort(keys)
- for _, k := range keys {
- if _, found := sinfo.FieldsMap[k.String()]; found {
- panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
- }
- e.marshal("", k)
- e.flow = false
- e.marshal("", m.MapIndex(k))
- }
- }
- }
- })
-}
-
-func (e *encoder) mappingv(tag string, f func()) {
- implicit := tag == ""
- style := yaml_BLOCK_MAPPING_STYLE
- if e.flow {
- e.flow = false
- style = yaml_FLOW_MAPPING_STYLE
- }
- e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
- e.emit()
- f()
- e.must(yaml_mapping_end_event_initialize(&e.event))
- e.emit()
-}
-
-func (e *encoder) slicev(tag string, in reflect.Value) {
- implicit := tag == ""
- style := yaml_BLOCK_SEQUENCE_STYLE
- if e.flow {
- e.flow = false
- style = yaml_FLOW_SEQUENCE_STYLE
- }
- e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
- e.emit()
- n := in.Len()
- for i := 0; i < n; i++ {
- e.marshal("", in.Index(i))
- }
- e.must(yaml_sequence_end_event_initialize(&e.event))
- e.emit()
-}
-
-// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
-//
-// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
-// in YAML 1.2 and by this package, but these should be marshalled quoted for
-// the time being for compatibility with other parsers.
-func isBase60Float(s string) (result bool) {
- // Fast path.
- if s == "" {
- return false
- }
- c := s[0]
- if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
- return false
- }
- // Do the full match.
- return base60float.MatchString(s)
-}
-
-// From http://yaml.org/type/float.html, except the regular expression there
-// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
-var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
-
-func (e *encoder) stringv(tag string, in reflect.Value) {
- var style yaml_scalar_style_t
- s := in.String()
- rtag, rs := resolve("", s)
- if rtag == yaml_BINARY_TAG {
- if tag == "" || tag == yaml_STR_TAG {
- tag = rtag
- s = rs.(string)
- } else if tag == yaml_BINARY_TAG {
- failf("explicitly tagged !!binary data must be base64-encoded")
- } else {
- failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
- }
- }
- if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
- style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- } else if strings.Contains(s, "\n") {
- style = yaml_LITERAL_SCALAR_STYLE
- } else {
- style = yaml_PLAIN_SCALAR_STYLE
- }
- e.emitScalar(s, "", tag, style)
-}
-
-func (e *encoder) boolv(tag string, in reflect.Value) {
- var s string
- if in.Bool() {
- s = "true"
- } else {
- s = "false"
- }
- e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) intv(tag string, in reflect.Value) {
- s := strconv.FormatInt(in.Int(), 10)
- e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) uintv(tag string, in reflect.Value) {
- s := strconv.FormatUint(in.Uint(), 10)
- e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) floatv(tag string, in reflect.Value) {
- // FIXME: Handle 64 bits here.
- s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
- switch s {
- case "+Inf":
- s = ".inf"
- case "-Inf":
- s = "-.inf"
- case "NaN":
- s = ".nan"
- }
- e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) nilv() {
- e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
- implicit := tag == ""
- e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
- e.emit()
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/parserc.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/parserc.go
deleted file mode 100644
index 0a7037ad1..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/parserc.go
+++ /dev/null
@@ -1,1096 +0,0 @@
-package yaml
-
-import (
- "bytes"
-)
-
-// The parser implements the following grammar:
-//
-// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
-// implicit_document ::= block_node DOCUMENT-END*
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-// block_node_or_indentless_sequence ::=
-// ALIAS
-// | properties (block_content | indentless_block_sequence)?
-// | block_content
-// | indentless_block_sequence
-// block_node ::= ALIAS
-// | properties block_content?
-// | block_content
-// flow_node ::= ALIAS
-// | properties flow_content?
-// | flow_content
-// properties ::= TAG ANCHOR? | ANCHOR TAG?
-// block_content ::= block_collection | flow_collection | SCALAR
-// flow_content ::= flow_collection | SCALAR
-// block_collection ::= block_sequence | block_mapping
-// flow_collection ::= flow_sequence | flow_mapping
-// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
-// block_mapping ::= BLOCK-MAPPING_START
-// ((KEY block_node_or_indentless_sequence?)?
-// (VALUE block_node_or_indentless_sequence?)?)*
-// BLOCK-END
-// flow_sequence ::= FLOW-SEQUENCE-START
-// (flow_sequence_entry FLOW-ENTRY)*
-// flow_sequence_entry?
-// FLOW-SEQUENCE-END
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// flow_mapping ::= FLOW-MAPPING-START
-// (flow_mapping_entry FLOW-ENTRY)*
-// flow_mapping_entry?
-// FLOW-MAPPING-END
-// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-
-// Peek the next token in the token queue.
-func peek_token(parser *yaml_parser_t) *yaml_token_t {
- if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
- return &parser.tokens[parser.tokens_head]
- }
- return nil
-}
-
-// Remove the next token from the queue (must be called after peek_token).
-func skip_token(parser *yaml_parser_t) {
- parser.token_available = false
- parser.tokens_parsed++
- parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
- parser.tokens_head++
-}
-
-// Get the next event.
-func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
- // Erase the event object.
- *event = yaml_event_t{}
-
- // No events after the end of the stream or error.
- if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
- return true
- }
-
- // Generate the next event.
- return yaml_parser_state_machine(parser, event)
-}
-
-// Set parser error.
-func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
- parser.error = yaml_PARSER_ERROR
- parser.problem = problem
- parser.problem_mark = problem_mark
- return false
-}
-
-func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
- parser.error = yaml_PARSER_ERROR
- parser.context = context
- parser.context_mark = context_mark
- parser.problem = problem
- parser.problem_mark = problem_mark
- return false
-}
-
-// State dispatcher.
-func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
- //trace("yaml_parser_state_machine", "state:", parser.state.String())
-
- switch parser.state {
- case yaml_PARSE_STREAM_START_STATE:
- return yaml_parser_parse_stream_start(parser, event)
-
- case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
- return yaml_parser_parse_document_start(parser, event, true)
-
- case yaml_PARSE_DOCUMENT_START_STATE:
- return yaml_parser_parse_document_start(parser, event, false)
-
- case yaml_PARSE_DOCUMENT_CONTENT_STATE:
- return yaml_parser_parse_document_content(parser, event)
-
- case yaml_PARSE_DOCUMENT_END_STATE:
- return yaml_parser_parse_document_end(parser, event)
-
- case yaml_PARSE_BLOCK_NODE_STATE:
- return yaml_parser_parse_node(parser, event, true, false)
-
- case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
- return yaml_parser_parse_node(parser, event, true, true)
-
- case yaml_PARSE_FLOW_NODE_STATE:
- return yaml_parser_parse_node(parser, event, false, false)
-
- case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
- return yaml_parser_parse_block_sequence_entry(parser, event, true)
-
- case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_block_sequence_entry(parser, event, false)
-
- case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_indentless_sequence_entry(parser, event)
-
- case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
- return yaml_parser_parse_block_mapping_key(parser, event, true)
-
- case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
- return yaml_parser_parse_block_mapping_key(parser, event, false)
-
- case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
- return yaml_parser_parse_block_mapping_value(parser, event)
-
- case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
- return yaml_parser_parse_flow_sequence_entry(parser, event, true)
-
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_flow_sequence_entry(parser, event, false)
-
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
-
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
-
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
-
- case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
- return yaml_parser_parse_flow_mapping_key(parser, event, true)
-
- case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
- return yaml_parser_parse_flow_mapping_key(parser, event, false)
-
- case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
- return yaml_parser_parse_flow_mapping_value(parser, event, false)
-
- case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
- return yaml_parser_parse_flow_mapping_value(parser, event, true)
-
- default:
- panic("invalid parser state")
- }
- return false
-}
-
-// Parse the production:
-// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
-// ************
-func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_STREAM_START_TOKEN {
- return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
- }
- parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
- *event = yaml_event_t{
- typ: yaml_STREAM_START_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- encoding: token.encoding,
- }
- skip_token(parser)
- return true
-}
-
-// Parse the productions:
-// implicit_document ::= block_node DOCUMENT-END*
-// *
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-// *************************
-func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- // Parse extra document end indicators.
- if !implicit {
- for token.typ == yaml_DOCUMENT_END_TOKEN {
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- }
- }
-
- if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
- token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
- token.typ != yaml_DOCUMENT_START_TOKEN &&
- token.typ != yaml_STREAM_END_TOKEN {
- // Parse an implicit document.
- if !yaml_parser_process_directives(parser, nil, nil) {
- return false
- }
- parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
- parser.state = yaml_PARSE_BLOCK_NODE_STATE
-
- *event = yaml_event_t{
- typ: yaml_DOCUMENT_START_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
-
- } else if token.typ != yaml_STREAM_END_TOKEN {
- // Parse an explicit document.
- var version_directive *yaml_version_directive_t
- var tag_directives []yaml_tag_directive_t
- start_mark := token.start_mark
- if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
- return false
- }
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_DOCUMENT_START_TOKEN {
- yaml_parser_set_parser_error(parser,
- "did not find expected <document start>", token.start_mark)
- return false
- }
- parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
- parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
- end_mark := token.end_mark
-
- *event = yaml_event_t{
- typ: yaml_DOCUMENT_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- version_directive: version_directive,
- tag_directives: tag_directives,
- implicit: false,
- }
- skip_token(parser)
-
- } else {
- // Parse the stream end.
- parser.state = yaml_PARSE_END_STATE
- *event = yaml_event_t{
- typ: yaml_STREAM_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
- skip_token(parser)
- }
-
- return true
-}
-
-// Parse the productions:
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-// ***********
-//
-func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
- token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
- token.typ == yaml_DOCUMENT_START_TOKEN ||
- token.typ == yaml_DOCUMENT_END_TOKEN ||
- token.typ == yaml_STREAM_END_TOKEN {
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- return yaml_parser_process_empty_scalar(parser, event,
- token.start_mark)
- }
- return yaml_parser_parse_node(parser, event, true, false)
-}
-
-// Parse the productions:
-// implicit_document ::= block_node DOCUMENT-END*
-// *************
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//
-func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- start_mark := token.start_mark
- end_mark := token.start_mark
-
- implicit := true
- if token.typ == yaml_DOCUMENT_END_TOKEN {
- end_mark = token.end_mark
- skip_token(parser)
- implicit = false
- }
-
- parser.tag_directives = parser.tag_directives[:0]
-
- parser.state = yaml_PARSE_DOCUMENT_START_STATE
- *event = yaml_event_t{
- typ: yaml_DOCUMENT_END_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- implicit: implicit,
- }
- return true
-}
-
-// Parse the productions:
-// block_node_or_indentless_sequence ::=
-// ALIAS
-// *****
-// | properties (block_content | indentless_block_sequence)?
-// ********** *
-// | block_content | indentless_block_sequence
-// *
-// block_node ::= ALIAS
-// *****
-// | properties block_content?
-// ********** *
-// | block_content
-// *
-// flow_node ::= ALIAS
-// *****
-// | properties flow_content?
-// ********** *
-// | flow_content
-// *
-// properties ::= TAG ANCHOR? | ANCHOR TAG?
-// *************************
-// block_content ::= block_collection | flow_collection | SCALAR
-// ******
-// flow_content ::= flow_collection | SCALAR
-// ******
-func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
- //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- if token.typ == yaml_ALIAS_TOKEN {
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- *event = yaml_event_t{
- typ: yaml_ALIAS_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- anchor: token.value,
- }
- skip_token(parser)
- return true
- }
-
- start_mark := token.start_mark
- end_mark := token.start_mark
-
- var tag_token bool
- var tag_handle, tag_suffix, anchor []byte
- var tag_mark yaml_mark_t
- if token.typ == yaml_ANCHOR_TOKEN {
- anchor = token.value
- start_mark = token.start_mark
- end_mark = token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ == yaml_TAG_TOKEN {
- tag_token = true
- tag_handle = token.value
- tag_suffix = token.suffix
- tag_mark = token.start_mark
- end_mark = token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- }
- } else if token.typ == yaml_TAG_TOKEN {
- tag_token = true
- tag_handle = token.value
- tag_suffix = token.suffix
- start_mark = token.start_mark
- tag_mark = token.start_mark
- end_mark = token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ == yaml_ANCHOR_TOKEN {
- anchor = token.value
- end_mark = token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- }
- }
-
- var tag []byte
- if tag_token {
- if len(tag_handle) == 0 {
- tag = tag_suffix
- tag_suffix = nil
- } else {
- for i := range parser.tag_directives {
- if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
- tag = append([]byte(nil), parser.tag_directives[i].prefix...)
- tag = append(tag, tag_suffix...)
- break
- }
- }
- if len(tag) == 0 {
- yaml_parser_set_parser_error_context(parser,
- "while parsing a node", start_mark,
- "found undefined tag handle", tag_mark)
- return false
- }
- }
- }
-
- implicit := len(tag) == 0
- if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
- end_mark = token.end_mark
- parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
- }
- return true
- }
- if token.typ == yaml_SCALAR_TOKEN {
- var plain_implicit, quoted_implicit bool
- end_mark = token.end_mark
- if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
- plain_implicit = true
- } else if len(tag) == 0 {
- quoted_implicit = true
- }
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
-
- *event = yaml_event_t{
- typ: yaml_SCALAR_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- value: token.value,
- implicit: plain_implicit,
- quoted_implicit: quoted_implicit,
- style: yaml_style_t(token.style),
- }
- skip_token(parser)
- return true
- }
- if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
- // [Go] Some of the events below can be merged as they differ only on style.
- end_mark = token.end_mark
- parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
- }
- return true
- }
- if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
- end_mark = token.end_mark
- parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
- *event = yaml_event_t{
- typ: yaml_MAPPING_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
- }
- return true
- }
- if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
- end_mark = token.end_mark
- parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
- }
- return true
- }
- if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
- end_mark = token.end_mark
- parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
- *event = yaml_event_t{
- typ: yaml_MAPPING_START_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
- }
- return true
- }
- if len(anchor) > 0 || len(tag) > 0 {
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
-
- *event = yaml_event_t{
- typ: yaml_SCALAR_EVENT,
- start_mark: start_mark,
- end_mark: end_mark,
- anchor: anchor,
- tag: tag,
- implicit: implicit,
- quoted_implicit: false,
- style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
- }
- return true
- }
-
- context := "while parsing a flow node"
- if block {
- context = "while parsing a block node"
- }
- yaml_parser_set_parser_error_context(parser, context, start_mark,
- "did not find expected node content", token.start_mark)
- return false
-}
-
-// Parse the productions:
-// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-// ******************** *********** * *********
-//
-func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
- if first {
- token := peek_token(parser)
- parser.marks = append(parser.marks, token.start_mark)
- skip_token(parser)
- }
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- if token.typ == yaml_BLOCK_ENTRY_TOKEN {
- mark := token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
- return yaml_parser_parse_node(parser, event, true, false)
- } else {
- parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
- return yaml_parser_process_empty_scalar(parser, event, mark)
- }
- }
- if token.typ == yaml_BLOCK_END_TOKEN {
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
-
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
-
- skip_token(parser)
- return true
- }
-
- context_mark := parser.marks[len(parser.marks)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- return yaml_parser_set_parser_error_context(parser,
- "while parsing a block collection", context_mark,
- "did not find expected '-' indicator", token.start_mark)
-}
-
-// Parse the productions:
-// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
-// *********** *
-func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- if token.typ == yaml_BLOCK_ENTRY_TOKEN {
- mark := token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
- token.typ != yaml_KEY_TOKEN &&
- token.typ != yaml_VALUE_TOKEN &&
- token.typ != yaml_BLOCK_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
- return yaml_parser_parse_node(parser, event, true, false)
- }
- parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
- return yaml_parser_process_empty_scalar(parser, event, mark)
- }
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
-
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark?
- }
- return true
-}
-
-// Parse the productions:
-// block_mapping ::= BLOCK-MAPPING_START
-// *******************
-// ((KEY block_node_or_indentless_sequence?)?
-// *** *
-// (VALUE block_node_or_indentless_sequence?)?)*
-//
-// BLOCK-END
-// *********
-//
-func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
- if first {
- token := peek_token(parser)
- parser.marks = append(parser.marks, token.start_mark)
- skip_token(parser)
- }
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- if token.typ == yaml_KEY_TOKEN {
- mark := token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_KEY_TOKEN &&
- token.typ != yaml_VALUE_TOKEN &&
- token.typ != yaml_BLOCK_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
- return yaml_parser_parse_node(parser, event, true, true)
- } else {
- parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
- return yaml_parser_process_empty_scalar(parser, event, mark)
- }
- } else if token.typ == yaml_BLOCK_END_TOKEN {
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- *event = yaml_event_t{
- typ: yaml_MAPPING_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
- skip_token(parser)
- return true
- }
-
- context_mark := parser.marks[len(parser.marks)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- return yaml_parser_set_parser_error_context(parser,
- "while parsing a block mapping", context_mark,
- "did not find expected key", token.start_mark)
-}
-
-// Parse the productions:
-// block_mapping ::= BLOCK-MAPPING_START
-//
-// ((KEY block_node_or_indentless_sequence?)?
-//
-// (VALUE block_node_or_indentless_sequence?)?)*
-// ***** *
-// BLOCK-END
-//
-//
-func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ == yaml_VALUE_TOKEN {
- mark := token.end_mark
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_KEY_TOKEN &&
- token.typ != yaml_VALUE_TOKEN &&
- token.typ != yaml_BLOCK_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
- return yaml_parser_parse_node(parser, event, true, true)
- }
- parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
- return yaml_parser_process_empty_scalar(parser, event, mark)
- }
- parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
- return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence ::= FLOW-SEQUENCE-START
-// *******************
-// (flow_sequence_entry FLOW-ENTRY)*
-// * **********
-// flow_sequence_entry?
-// *
-// FLOW-SEQUENCE-END
-// *****************
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// *
-//
-func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
- if first {
- token := peek_token(parser)
- parser.marks = append(parser.marks, token.start_mark)
- skip_token(parser)
- }
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
- if !first {
- if token.typ == yaml_FLOW_ENTRY_TOKEN {
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- } else {
- context_mark := parser.marks[len(parser.marks)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- return yaml_parser_set_parser_error_context(parser,
- "while parsing a flow sequence", context_mark,
- "did not find expected ',' or ']'", token.start_mark)
- }
- }
-
- if token.typ == yaml_KEY_TOKEN {
- parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
- *event = yaml_event_t{
- typ: yaml_MAPPING_START_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- implicit: true,
- style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
- }
- skip_token(parser)
- return true
- } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- }
- }
-
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
-
- *event = yaml_event_t{
- typ: yaml_SEQUENCE_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
-
- skip_token(parser)
- return true
-}
-
-//
-// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// *** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_VALUE_TOKEN &&
- token.typ != yaml_FLOW_ENTRY_TOKEN &&
- token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- }
- mark := token.end_mark
- skip_token(parser)
- parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
- return yaml_parser_process_empty_scalar(parser, event, mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// ***** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ == yaml_VALUE_TOKEN {
- skip_token(parser)
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- }
- }
- parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
- return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
- *event = yaml_event_t{
- typ: yaml_MAPPING_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.start_mark, // [Go] Shouldn't this be end_mark?
- }
- return true
-}
-
-// Parse the productions:
-// flow_mapping ::= FLOW-MAPPING-START
-// ******************
-// (flow_mapping_entry FLOW-ENTRY)*
-// * **********
-// flow_mapping_entry?
-// ******************
-// FLOW-MAPPING-END
-// ****************
-// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// * *** *
-//
-func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
- if first {
- token := peek_token(parser)
- parser.marks = append(parser.marks, token.start_mark)
- skip_token(parser)
- }
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
- if !first {
- if token.typ == yaml_FLOW_ENTRY_TOKEN {
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- } else {
- context_mark := parser.marks[len(parser.marks)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- return yaml_parser_set_parser_error_context(parser,
- "while parsing a flow mapping", context_mark,
- "did not find expected ',' or '}'", token.start_mark)
- }
- }
-
- if token.typ == yaml_KEY_TOKEN {
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_VALUE_TOKEN &&
- token.typ != yaml_FLOW_ENTRY_TOKEN &&
- token.typ != yaml_FLOW_MAPPING_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- } else {
- parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
- return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
- }
- } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- }
- }
-
- parser.state = parser.states[len(parser.states)-1]
- parser.states = parser.states[:len(parser.states)-1]
- parser.marks = parser.marks[:len(parser.marks)-1]
- *event = yaml_event_t{
- typ: yaml_MAPPING_END_EVENT,
- start_mark: token.start_mark,
- end_mark: token.end_mark,
- }
- skip_token(parser)
- return true
-}
-
-// Parse the productions:
-// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// * ***** *
-//
-func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
- token := peek_token(parser)
- if token == nil {
- return false
- }
- if empty {
- parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
- return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
- }
- if token.typ == yaml_VALUE_TOKEN {
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
- parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
- return yaml_parser_parse_node(parser, event, false, false)
- }
- }
- parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
- return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Generate an empty scalar event.
-func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
- *event = yaml_event_t{
- typ: yaml_SCALAR_EVENT,
- start_mark: mark,
- end_mark: mark,
- value: nil, // Empty
- implicit: true,
- style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
- }
- return true
-}
-
-var default_tag_directives = []yaml_tag_directive_t{
- {[]byte("!"), []byte("!")},
- {[]byte("!!"), []byte("tag:yaml.org,2002:")},
-}
-
-// Parse directives.
-func yaml_parser_process_directives(parser *yaml_parser_t,
- version_directive_ref **yaml_version_directive_t,
- tag_directives_ref *[]yaml_tag_directive_t) bool {
-
- var version_directive *yaml_version_directive_t
- var tag_directives []yaml_tag_directive_t
-
- token := peek_token(parser)
- if token == nil {
- return false
- }
-
- for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
- if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
- if version_directive != nil {
- yaml_parser_set_parser_error(parser,
- "found duplicate %YAML directive", token.start_mark)
- return false
- }
- if token.major != 1 || token.minor != 1 {
- yaml_parser_set_parser_error(parser,
- "found incompatible YAML document", token.start_mark)
- return false
- }
- version_directive = &yaml_version_directive_t{
- major: token.major,
- minor: token.minor,
- }
- } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
- value := yaml_tag_directive_t{
- handle: token.value,
- prefix: token.prefix,
- }
- if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
- return false
- }
- tag_directives = append(tag_directives, value)
- }
-
- skip_token(parser)
- token = peek_token(parser)
- if token == nil {
- return false
- }
- }
-
- for i := range default_tag_directives {
- if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
- return false
- }
- }
-
- if version_directive_ref != nil {
- *version_directive_ref = version_directive
- }
- if tag_directives_ref != nil {
- *tag_directives_ref = tag_directives
- }
- return true
-}
-
-// Append a tag directive to the directives stack.
-func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
- for i := range parser.tag_directives {
- if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
- if allow_duplicates {
- return true
- }
- return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
- }
- }
-
- // [Go] I suspect the copy is unnecessary. This was likely done
- // because there was no way to track ownership of the data.
- value_copy := yaml_tag_directive_t{
- handle: make([]byte, len(value.handle)),
- prefix: make([]byte, len(value.prefix)),
- }
- copy(value_copy.handle, value.handle)
- copy(value_copy.prefix, value.prefix)
- parser.tag_directives = append(parser.tag_directives, value_copy)
- return true
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/readerc.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/readerc.go
deleted file mode 100644
index f45079171..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/readerc.go
+++ /dev/null
@@ -1,394 +0,0 @@
-package yaml
-
-import (
- "io"
-)
-
-// Set the reader error and return 0.
-func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
- parser.error = yaml_READER_ERROR
- parser.problem = problem
- parser.problem_offset = offset
- parser.problem_value = value
- return false
-}
-
-// Byte order marks.
-const (
- bom_UTF8 = "\xef\xbb\xbf"
- bom_UTF16LE = "\xff\xfe"
- bom_UTF16BE = "\xfe\xff"
-)
-
-// Determine the input stream encoding by checking the BOM symbol. If no BOM is
-// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
-func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
- // Ensure that we had enough bytes in the raw buffer.
- for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
- if !yaml_parser_update_raw_buffer(parser) {
- return false
- }
- }
-
- // Determine the encoding.
- buf := parser.raw_buffer
- pos := parser.raw_buffer_pos
- avail := len(buf) - pos
- if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
- parser.encoding = yaml_UTF16LE_ENCODING
- parser.raw_buffer_pos += 2
- parser.offset += 2
- } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
- parser.encoding = yaml_UTF16BE_ENCODING
- parser.raw_buffer_pos += 2
- parser.offset += 2
- } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
- parser.encoding = yaml_UTF8_ENCODING
- parser.raw_buffer_pos += 3
- parser.offset += 3
- } else {
- parser.encoding = yaml_UTF8_ENCODING
- }
- return true
-}
-
-// Update the raw buffer.
-func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
- size_read := 0
-
- // Return if the raw buffer is full.
- if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
- return true
- }
-
- // Return on EOF.
- if parser.eof {
- return true
- }
-
- // Move the remaining bytes in the raw buffer to the beginning.
- if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
- copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
- }
- parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
- parser.raw_buffer_pos = 0
-
- // Call the read handler to fill the buffer.
- size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
- parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
- if err == io.EOF {
- parser.eof = true
- } else if err != nil {
- return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
- }
- return true
-}
-
-// Ensure that the buffer contains at least `length` characters.
-// Return true on success, false on failure.
-//
-// The length is supposed to be significantly less that the buffer size.
-func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
- if parser.read_handler == nil {
- panic("read handler must be set")
- }
-
- // If the EOF flag is set and the raw buffer is empty, do nothing.
- if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
- return true
- }
-
- // Return if the buffer contains enough characters.
- if parser.unread >= length {
- return true
- }
-
- // Determine the input encoding if it is not known yet.
- if parser.encoding == yaml_ANY_ENCODING {
- if !yaml_parser_determine_encoding(parser) {
- return false
- }
- }
-
- // Move the unread characters to the beginning of the buffer.
- buffer_len := len(parser.buffer)
- if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
- copy(parser.buffer, parser.buffer[parser.buffer_pos:])
- buffer_len -= parser.buffer_pos
- parser.buffer_pos = 0
- } else if parser.buffer_pos == buffer_len {
- buffer_len = 0
- parser.buffer_pos = 0
- }
-
- // Open the whole buffer for writing, and cut it before returning.
- parser.buffer = parser.buffer[:cap(parser.buffer)]
-
- // Fill the buffer until it has enough characters.
- first := true
- for parser.unread < length {
-
- // Fill the raw buffer if necessary.
- if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
- if !yaml_parser_update_raw_buffer(parser) {
- parser.buffer = parser.buffer[:buffer_len]
- return false
- }
- }
- first = false
-
- // Decode the raw buffer.
- inner:
- for parser.raw_buffer_pos != len(parser.raw_buffer) {
- var value rune
- var width int
-
- raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
-
- // Decode the next character.
- switch parser.encoding {
- case yaml_UTF8_ENCODING:
- // Decode a UTF-8 character. Check RFC 3629
- // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
- //
- // The following table (taken from the RFC) is used for
- // decoding.
- //
- // Char. number range | UTF-8 octet sequence
- // (hexadecimal) | (binary)
- // --------------------+------------------------------------
- // 0000 0000-0000 007F | 0xxxxxxx
- // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
- // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
- // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- //
- // Additionally, the characters in the range 0xD800-0xDFFF
- // are prohibited as they are reserved for use with UTF-16
- // surrogate pairs.
-
- // Determine the length of the UTF-8 sequence.
- octet := parser.raw_buffer[parser.raw_buffer_pos]
- switch {
- case octet&0x80 == 0x00:
- width = 1
- case octet&0xE0 == 0xC0:
- width = 2
- case octet&0xF0 == 0xE0:
- width = 3
- case octet&0xF8 == 0xF0:
- width = 4
- default:
- // The leading octet is invalid.
- return yaml_parser_set_reader_error(parser,
- "invalid leading UTF-8 octet",
- parser.offset, int(octet))
- }
-
- // Check if the raw buffer contains an incomplete character.
- if width > raw_unread {
- if parser.eof {
- return yaml_parser_set_reader_error(parser,
- "incomplete UTF-8 octet sequence",
- parser.offset, -1)
- }
- break inner
- }
-
- // Decode the leading octet.
- switch {
- case octet&0x80 == 0x00:
- value = rune(octet & 0x7F)
- case octet&0xE0 == 0xC0:
- value = rune(octet & 0x1F)
- case octet&0xF0 == 0xE0:
- value = rune(octet & 0x0F)
- case octet&0xF8 == 0xF0:
- value = rune(octet & 0x07)
- default:
- value = 0
- }
-
- // Check and decode the trailing octets.
- for k := 1; k < width; k++ {
- octet = parser.raw_buffer[parser.raw_buffer_pos+k]
-
- // Check if the octet is valid.
- if (octet & 0xC0) != 0x80 {
- return yaml_parser_set_reader_error(parser,
- "invalid trailing UTF-8 octet",
- parser.offset+k, int(octet))
- }
-
- // Decode the octet.
- value = (value << 6) + rune(octet&0x3F)
- }
-
- // Check the length of the sequence against the value.
- switch {
- case width == 1:
- case width == 2 && value >= 0x80:
- case width == 3 && value >= 0x800:
- case width == 4 && value >= 0x10000:
- default:
- return yaml_parser_set_reader_error(parser,
- "invalid length of a UTF-8 sequence",
- parser.offset, -1)
- }
-
- // Check the range of the value.
- if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
- return yaml_parser_set_reader_error(parser,
- "invalid Unicode character",
- parser.offset, int(value))
- }
-
- case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
- var low, high int
- if parser.encoding == yaml_UTF16LE_ENCODING {
- low, high = 0, 1
- } else {
- low, high = 1, 0
- }
-
- // The UTF-16 encoding is not as simple as one might
- // naively think. Check RFC 2781
- // (http://www.ietf.org/rfc/rfc2781.txt).
- //
- // Normally, two subsequent bytes describe a Unicode
- // character. However a special technique (called a
- // surrogate pair) is used for specifying character
- // values larger than 0xFFFF.
- //
- // A surrogate pair consists of two pseudo-characters:
- // high surrogate area (0xD800-0xDBFF)
- // low surrogate area (0xDC00-0xDFFF)
- //
- // The following formulas are used for decoding
- // and encoding characters using surrogate pairs:
- //
- // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
- // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
- // W1 = 110110yyyyyyyyyy
- // W2 = 110111xxxxxxxxxx
- //
- // where U is the character value, W1 is the high surrogate
- // area, W2 is the low surrogate area.
-
- // Check for incomplete UTF-16 character.
- if raw_unread < 2 {
- if parser.eof {
- return yaml_parser_set_reader_error(parser,
- "incomplete UTF-16 character",
- parser.offset, -1)
- }
- break inner
- }
-
- // Get the character.
- value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
- (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
-
- // Check for unexpected low surrogate area.
- if value&0xFC00 == 0xDC00 {
- return yaml_parser_set_reader_error(parser,
- "unexpected low surrogate area",
- parser.offset, int(value))
- }
-
- // Check for a high surrogate area.
- if value&0xFC00 == 0xD800 {
- width = 4
-
- // Check for incomplete surrogate pair.
- if raw_unread < 4 {
- if parser.eof {
- return yaml_parser_set_reader_error(parser,
- "incomplete UTF-16 surrogate pair",
- parser.offset, -1)
- }
- break inner
- }
-
- // Get the next character.
- value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
- (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
-
- // Check for a low surrogate area.
- if value2&0xFC00 != 0xDC00 {
- return yaml_parser_set_reader_error(parser,
- "expected low surrogate area",
- parser.offset+2, int(value2))
- }
-
- // Generate the value of the surrogate pair.
- value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
- } else {
- width = 2
- }
-
- default:
- panic("impossible")
- }
-
- // Check if the character is in the allowed range:
- // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
- // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
- // | [#x10000-#x10FFFF] (32 bit)
- switch {
- case value == 0x09:
- case value == 0x0A:
- case value == 0x0D:
- case value >= 0x20 && value <= 0x7E:
- case value == 0x85:
- case value >= 0xA0 && value <= 0xD7FF:
- case value >= 0xE000 && value <= 0xFFFD:
- case value >= 0x10000 && value <= 0x10FFFF:
- default:
- return yaml_parser_set_reader_error(parser,
- "control characters are not allowed",
- parser.offset, int(value))
- }
-
- // Move the raw pointers.
- parser.raw_buffer_pos += width
- parser.offset += width
-
- // Finally put the character into the buffer.
- if value <= 0x7F {
- // 0000 0000-0000 007F . 0xxxxxxx
- parser.buffer[buffer_len+0] = byte(value)
- buffer_len += 1
- } else if value <= 0x7FF {
- // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
- parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
- parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
- buffer_len += 2
- } else if value <= 0xFFFF {
- // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
- parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
- parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
- parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
- buffer_len += 3
- } else {
- // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
- parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
- parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
- parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
- buffer_len += 4
- }
-
- parser.unread++
- }
-
- // On EOF, put NUL into the buffer and return.
- if parser.eof {
- parser.buffer[buffer_len] = 0
- buffer_len++
- parser.unread++
- break
- }
- }
- parser.buffer = parser.buffer[:buffer_len]
- return true
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/resolve.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/resolve.go
deleted file mode 100644
index 93a863274..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/resolve.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package yaml
-
-import (
- "encoding/base64"
- "math"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-type resolveMapItem struct {
- value interface{}
- tag string
-}
-
-var resolveTable = make([]byte, 256)
-var resolveMap = make(map[string]resolveMapItem)
-
-func init() {
- t := resolveTable
- t[int('+')] = 'S' // Sign
- t[int('-')] = 'S'
- for _, c := range "0123456789" {
- t[int(c)] = 'D' // Digit
- }
- for _, c := range "yYnNtTfFoO~" {
- t[int(c)] = 'M' // In map
- }
- t[int('.')] = '.' // Float (potentially in map)
-
- var resolveMapList = []struct {
- v interface{}
- tag string
- l []string
- }{
- {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
- {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
- {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
- {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
- {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
- {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
- {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
- {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
- {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
- {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
- {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
- {"<<", yaml_MERGE_TAG, []string{"<<"}},
- }
-
- m := resolveMap
- for _, item := range resolveMapList {
- for _, s := range item.l {
- m[s] = resolveMapItem{item.v, item.tag}
- }
- }
-}
-
-const longTagPrefix = "tag:yaml.org,2002:"
-
-func shortTag(tag string) string {
- // TODO This can easily be made faster and produce less garbage.
- if strings.HasPrefix(tag, longTagPrefix) {
- return "!!" + tag[len(longTagPrefix):]
- }
- return tag
-}
-
-func longTag(tag string) string {
- if strings.HasPrefix(tag, "!!") {
- return longTagPrefix + tag[2:]
- }
- return tag
-}
-
-func resolvableTag(tag string) bool {
- switch tag {
- case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
- return true
- }
- return false
-}
-
-func resolve(tag string, in string) (rtag string, out interface{}) {
- if !resolvableTag(tag) {
- return tag, in
- }
-
- defer func() {
- switch tag {
- case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
- return
- }
- failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
- }()
-
- // Any data is accepted as a !!str or !!binary.
- // Otherwise, the prefix is enough of a hint about what it might be.
- hint := byte('N')
- if in != "" {
- hint = resolveTable[in[0]]
- }
- if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
- // Handle things we can lookup in a map.
- if item, ok := resolveMap[in]; ok {
- return item.tag, item.value
- }
-
- // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
- // are purposefully unsupported here. They're still quoted on
- // the way out for compatibility with other parser, though.
-
- switch hint {
- case 'M':
- // We've already checked the map above.
-
- case '.':
- // Not in the map, so maybe a normal float.
- floatv, err := strconv.ParseFloat(in, 64)
- if err == nil {
- return yaml_FLOAT_TAG, floatv
- }
-
- case 'D', 'S':
- // Int, float, or timestamp.
- plain := strings.Replace(in, "_", "", -1)
- intv, err := strconv.ParseInt(plain, 0, 64)
- if err == nil {
- if intv == int64(int(intv)) {
- return yaml_INT_TAG, int(intv)
- } else {
- return yaml_INT_TAG, intv
- }
- }
- uintv, err := strconv.ParseUint(plain, 0, 64)
- if err == nil {
- return yaml_INT_TAG, uintv
- }
- floatv, err := strconv.ParseFloat(plain, 64)
- if err == nil {
- return yaml_FLOAT_TAG, floatv
- }
- if strings.HasPrefix(plain, "0b") {
- intv, err := strconv.ParseInt(plain[2:], 2, 64)
- if err == nil {
- if intv == int64(int(intv)) {
- return yaml_INT_TAG, int(intv)
- } else {
- return yaml_INT_TAG, intv
- }
- }
- uintv, err := strconv.ParseUint(plain[2:], 2, 64)
- if err == nil {
- return yaml_INT_TAG, uintv
- }
- } else if strings.HasPrefix(plain, "-0b") {
- intv, err := strconv.ParseInt(plain[3:], 2, 64)
- if err == nil {
- if intv == int64(int(intv)) {
- return yaml_INT_TAG, -int(intv)
- } else {
- return yaml_INT_TAG, -intv
- }
- }
- }
- // XXX Handle timestamps here.
-
- default:
- panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
- }
- }
- if tag == yaml_BINARY_TAG {
- return yaml_BINARY_TAG, in
- }
- if utf8.ValidString(in) {
- return yaml_STR_TAG, in
- }
- return yaml_BINARY_TAG, encodeBase64(in)
-}
-
-// encodeBase64 encodes s as base64 that is broken up into multiple lines
-// as appropriate for the resulting length.
-func encodeBase64(s string) string {
- const lineLen = 70
- encLen := base64.StdEncoding.EncodedLen(len(s))
- lines := encLen/lineLen + 1
- buf := make([]byte, encLen*2+lines)
- in := buf[0:encLen]
- out := buf[encLen:]
- base64.StdEncoding.Encode(in, []byte(s))
- k := 0
- for i := 0; i < len(in); i += lineLen {
- j := i + lineLen
- if j > len(in) {
- j = len(in)
- }
- k += copy(out[k:], in[i:j])
- if lines > 1 {
- out[k] = '\n'
- k++
- }
- }
- return string(out[:k])
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/scannerc.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/scannerc.go
deleted file mode 100644
index d97d76fa5..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/scannerc.go
+++ /dev/null
@@ -1,2710 +0,0 @@
-package yaml
-
-import (
- "bytes"
- "fmt"
-)
-
-// Introduction
-// ************
-//
-// The following notes assume that you are familiar with the YAML specification
-// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
-// some cases we are less restrictive that it requires.
-//
-// The process of transforming a YAML stream into a sequence of events is
-// divided on two steps: Scanning and Parsing.
-//
-// The Scanner transforms the input stream into a sequence of tokens, while the
-// parser transform the sequence of tokens produced by the Scanner into a
-// sequence of parsing events.
-//
-// The Scanner is rather clever and complicated. The Parser, on the contrary,
-// is a straightforward implementation of a recursive-descendant parser (or,
-// LL(1) parser, as it is usually called).
-//
-// Actually there are two issues of Scanning that might be called "clever", the
-// rest is quite straightforward. The issues are "block collection start" and
-// "simple keys". Both issues are explained below in details.
-//
-// Here the Scanning step is explained and implemented. We start with the list
-// of all the tokens produced by the Scanner together with short descriptions.
-//
-// Now, tokens:
-//
-// STREAM-START(encoding) # The stream start.
-// STREAM-END # The stream end.
-// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
-// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
-// DOCUMENT-START # '---'
-// DOCUMENT-END # '...'
-// BLOCK-SEQUENCE-START # Indentation increase denoting a block
-// BLOCK-MAPPING-START # sequence or a block mapping.
-// BLOCK-END # Indentation decrease.
-// FLOW-SEQUENCE-START # '['
-// FLOW-SEQUENCE-END # ']'
-// BLOCK-SEQUENCE-START # '{'
-// BLOCK-SEQUENCE-END # '}'
-// BLOCK-ENTRY # '-'
-// FLOW-ENTRY # ','
-// KEY # '?' or nothing (simple keys).
-// VALUE # ':'
-// ALIAS(anchor) # '*anchor'
-// ANCHOR(anchor) # '&anchor'
-// TAG(handle,suffix) # '!handle!suffix'
-// SCALAR(value,style) # A scalar.
-//
-// The following two tokens are "virtual" tokens denoting the beginning and the
-// end of the stream:
-//
-// STREAM-START(encoding)
-// STREAM-END
-//
-// We pass the information about the input stream encoding with the
-// STREAM-START token.
-//
-// The next two tokens are responsible for tags:
-//
-// VERSION-DIRECTIVE(major,minor)
-// TAG-DIRECTIVE(handle,prefix)
-//
-// Example:
-//
-// %YAML 1.1
-// %TAG ! !foo
-// %TAG !yaml! tag:yaml.org,2002:
-// ---
-//
-// The correspoding sequence of tokens:
-//
-// STREAM-START(utf-8)
-// VERSION-DIRECTIVE(1,1)
-// TAG-DIRECTIVE("!","!foo")
-// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
-// DOCUMENT-START
-// STREAM-END
-//
-// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
-// line.
-//
-// The document start and end indicators are represented by:
-//
-// DOCUMENT-START
-// DOCUMENT-END
-//
-// Note that if a YAML stream contains an implicit document (without '---'
-// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
-// produced.
-//
-// In the following examples, we present whole documents together with the
-// produced tokens.
-//
-// 1. An implicit document:
-//
-// 'a scalar'
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// SCALAR("a scalar",single-quoted)
-// STREAM-END
-//
-// 2. An explicit document:
-//
-// ---
-// 'a scalar'
-// ...
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// DOCUMENT-START
-// SCALAR("a scalar",single-quoted)
-// DOCUMENT-END
-// STREAM-END
-//
-// 3. Several documents in a stream:
-//
-// 'a scalar'
-// ---
-// 'another scalar'
-// ---
-// 'yet another scalar'
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// SCALAR("a scalar",single-quoted)
-// DOCUMENT-START
-// SCALAR("another scalar",single-quoted)
-// DOCUMENT-START
-// SCALAR("yet another scalar",single-quoted)
-// STREAM-END
-//
-// We have already introduced the SCALAR token above. The following tokens are
-// used to describe aliases, anchors, tag, and scalars:
-//
-// ALIAS(anchor)
-// ANCHOR(anchor)
-// TAG(handle,suffix)
-// SCALAR(value,style)
-//
-// The following series of examples illustrate the usage of these tokens:
-//
-// 1. A recursive sequence:
-//
-// &A [ *A ]
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// ANCHOR("A")
-// FLOW-SEQUENCE-START
-// ALIAS("A")
-// FLOW-SEQUENCE-END
-// STREAM-END
-//
-// 2. A tagged scalar:
-//
-// !!float "3.14" # A good approximation.
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// TAG("!!","float")
-// SCALAR("3.14",double-quoted)
-// STREAM-END
-//
-// 3. Various scalar styles:
-//
-// --- # Implicit empty plain scalars do not produce tokens.
-// --- a plain scalar
-// --- 'a single-quoted scalar'
-// --- "a double-quoted scalar"
-// --- |-
-// a literal scalar
-// --- >-
-// a folded
-// scalar
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// DOCUMENT-START
-// DOCUMENT-START
-// SCALAR("a plain scalar",plain)
-// DOCUMENT-START
-// SCALAR("a single-quoted scalar",single-quoted)
-// DOCUMENT-START
-// SCALAR("a double-quoted scalar",double-quoted)
-// DOCUMENT-START
-// SCALAR("a literal scalar",literal)
-// DOCUMENT-START
-// SCALAR("a folded scalar",folded)
-// STREAM-END
-//
-// Now it's time to review collection-related tokens. We will start with
-// flow collections:
-//
-// FLOW-SEQUENCE-START
-// FLOW-SEQUENCE-END
-// FLOW-MAPPING-START
-// FLOW-MAPPING-END
-// FLOW-ENTRY
-// KEY
-// VALUE
-//
-// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
-// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
-// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
-// indicators '?' and ':', which are used for denoting mapping keys and values,
-// are represented by the KEY and VALUE tokens.
-//
-// The following examples show flow collections:
-//
-// 1. A flow sequence:
-//
-// [item 1, item 2, item 3]
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// FLOW-SEQUENCE-START
-// SCALAR("item 1",plain)
-// FLOW-ENTRY
-// SCALAR("item 2",plain)
-// FLOW-ENTRY
-// SCALAR("item 3",plain)
-// FLOW-SEQUENCE-END
-// STREAM-END
-//
-// 2. A flow mapping:
-//
-// {
-// a simple key: a value, # Note that the KEY token is produced.
-// ? a complex key: another value,
-// }
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// FLOW-MAPPING-START
-// KEY
-// SCALAR("a simple key",plain)
-// VALUE
-// SCALAR("a value",plain)
-// FLOW-ENTRY
-// KEY
-// SCALAR("a complex key",plain)
-// VALUE
-// SCALAR("another value",plain)
-// FLOW-ENTRY
-// FLOW-MAPPING-END
-// STREAM-END
-//
-// A simple key is a key which is not denoted by the '?' indicator. Note that
-// the Scanner still produce the KEY token whenever it encounters a simple key.
-//
-// For scanning block collections, the following tokens are used (note that we
-// repeat KEY and VALUE here):
-//
-// BLOCK-SEQUENCE-START
-// BLOCK-MAPPING-START
-// BLOCK-END
-// BLOCK-ENTRY
-// KEY
-// VALUE
-//
-// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
-// increase that precedes a block collection (cf. the INDENT token in Python).
-// The token BLOCK-END denote indentation decrease that ends a block collection
-// (cf. the DEDENT token in Python). However YAML has some syntax pecularities
-// that makes detections of these tokens more complex.
-//
-// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
-// '-', '?', and ':' correspondingly.
-//
-// The following examples show how the tokens BLOCK-SEQUENCE-START,
-// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
-//
-// 1. Block sequences:
-//
-// - item 1
-// - item 2
-// -
-// - item 3.1
-// - item 3.2
-// -
-// key 1: value 1
-// key 2: value 2
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// SCALAR("item 1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 2",plain)
-// BLOCK-ENTRY
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// SCALAR("item 3.1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 3.2",plain)
-// BLOCK-END
-// BLOCK-ENTRY
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("key 1",plain)
-// VALUE
-// SCALAR("value 1",plain)
-// KEY
-// SCALAR("key 2",plain)
-// VALUE
-// SCALAR("value 2",plain)
-// BLOCK-END
-// BLOCK-END
-// STREAM-END
-//
-// 2. Block mappings:
-//
-// a simple key: a value # The KEY token is produced here.
-// ? a complex key
-// : another value
-// a mapping:
-// key 1: value 1
-// key 2: value 2
-// a sequence:
-// - item 1
-// - item 2
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("a simple key",plain)
-// VALUE
-// SCALAR("a value",plain)
-// KEY
-// SCALAR("a complex key",plain)
-// VALUE
-// SCALAR("another value",plain)
-// KEY
-// SCALAR("a mapping",plain)
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("key 1",plain)
-// VALUE
-// SCALAR("value 1",plain)
-// KEY
-// SCALAR("key 2",plain)
-// VALUE
-// SCALAR("value 2",plain)
-// BLOCK-END
-// KEY
-// SCALAR("a sequence",plain)
-// VALUE
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// SCALAR("item 1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 2",plain)
-// BLOCK-END
-// BLOCK-END
-// STREAM-END
-//
-// YAML does not always require to start a new block collection from a new
-// line. If the current line contains only '-', '?', and ':' indicators, a new
-// block collection may start at the current line. The following examples
-// illustrate this case:
-//
-// 1. Collections in a sequence:
-//
-// - - item 1
-// - item 2
-// - key 1: value 1
-// key 2: value 2
-// - ? complex key
-// : complex value
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// SCALAR("item 1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 2",plain)
-// BLOCK-END
-// BLOCK-ENTRY
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("key 1",plain)
-// VALUE
-// SCALAR("value 1",plain)
-// KEY
-// SCALAR("key 2",plain)
-// VALUE
-// SCALAR("value 2",plain)
-// BLOCK-END
-// BLOCK-ENTRY
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("complex key")
-// VALUE
-// SCALAR("complex value")
-// BLOCK-END
-// BLOCK-END
-// STREAM-END
-//
-// 2. Collections in a mapping:
-//
-// ? a sequence
-// : - item 1
-// - item 2
-// ? a mapping
-// : key 1: value 1
-// key 2: value 2
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("a sequence",plain)
-// VALUE
-// BLOCK-SEQUENCE-START
-// BLOCK-ENTRY
-// SCALAR("item 1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 2",plain)
-// BLOCK-END
-// KEY
-// SCALAR("a mapping",plain)
-// VALUE
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("key 1",plain)
-// VALUE
-// SCALAR("value 1",plain)
-// KEY
-// SCALAR("key 2",plain)
-// VALUE
-// SCALAR("value 2",plain)
-// BLOCK-END
-// BLOCK-END
-// STREAM-END
-//
-// YAML also permits non-indented sequences if they are included into a block
-// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
-//
-// key:
-// - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
-// - item 2
-//
-// Tokens:
-//
-// STREAM-START(utf-8)
-// BLOCK-MAPPING-START
-// KEY
-// SCALAR("key",plain)
-// VALUE
-// BLOCK-ENTRY
-// SCALAR("item 1",plain)
-// BLOCK-ENTRY
-// SCALAR("item 2",plain)
-// BLOCK-END
-//
-
-// Ensure that the buffer contains the required number of characters.
-// Return true on success, false on failure (reader error or memory error).
-func cache(parser *yaml_parser_t, length int) bool {
- // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
- return parser.unread >= length || yaml_parser_update_buffer(parser, length)
-}
-
-// Advance the buffer pointer.
-func skip(parser *yaml_parser_t) {
- parser.mark.index++
- parser.mark.column++
- parser.unread--
- parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
-}
-
-func skip_line(parser *yaml_parser_t) {
- if is_crlf(parser.buffer, parser.buffer_pos) {
- parser.mark.index += 2
- parser.mark.column = 0
- parser.mark.line++
- parser.unread -= 2
- parser.buffer_pos += 2
- } else if is_break(parser.buffer, parser.buffer_pos) {
- parser.mark.index++
- parser.mark.column = 0
- parser.mark.line++
- parser.unread--
- parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
- }
-}
-
-// Copy a character to a string buffer and advance pointers.
-func read(parser *yaml_parser_t, s []byte) []byte {
- w := width(parser.buffer[parser.buffer_pos])
- if w == 0 {
- panic("invalid character sequence")
- }
- if len(s) == 0 {
- s = make([]byte, 0, 32)
- }
- if w == 1 && len(s)+w <= cap(s) {
- s = s[:len(s)+1]
- s[len(s)-1] = parser.buffer[parser.buffer_pos]
- parser.buffer_pos++
- } else {
- s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
- parser.buffer_pos += w
- }
- parser.mark.index++
- parser.mark.column++
- parser.unread--
- return s
-}
-
-// Copy a line break character to a string buffer and advance pointers.
-func read_line(parser *yaml_parser_t, s []byte) []byte {
- buf := parser.buffer
- pos := parser.buffer_pos
- switch {
- case buf[pos] == '\r' && buf[pos+1] == '\n':
- // CR LF . LF
- s = append(s, '\n')
- parser.buffer_pos += 2
- parser.mark.index++
- parser.unread--
- case buf[pos] == '\r' || buf[pos] == '\n':
- // CR|LF . LF
- s = append(s, '\n')
- parser.buffer_pos += 1
- case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
- // NEL . LF
- s = append(s, '\n')
- parser.buffer_pos += 2
- case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
- // LS|PS . LS|PS
- s = append(s, buf[parser.buffer_pos:pos+3]...)
- parser.buffer_pos += 3
- default:
- return s
- }
- parser.mark.index++
- parser.mark.column = 0
- parser.mark.line++
- parser.unread--
- return s
-}
-
-// Get the next token.
-func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
- // Erase the token object.
- *token = yaml_token_t{} // [Go] Is this necessary?
-
- // No tokens after STREAM-END or error.
- if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
- return true
- }
-
- // Ensure that the tokens queue contains enough tokens.
- if !parser.token_available {
- if !yaml_parser_fetch_more_tokens(parser) {
- return false
- }
- }
-
- // Fetch the next token from the queue.
- *token = parser.tokens[parser.tokens_head]
- parser.tokens_head++
- parser.tokens_parsed++
- parser.token_available = false
-
- if token.typ == yaml_STREAM_END_TOKEN {
- parser.stream_end_produced = true
- }
- return true
-}
-
-// Set the scanner error and return false.
-func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
- parser.error = yaml_SCANNER_ERROR
- parser.context = context
- parser.context_mark = context_mark
- parser.problem = problem
- parser.problem_mark = parser.mark
- return false
-}
-
-func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
- context := "while parsing a tag"
- if directive {
- context = "while parsing a %TAG directive"
- }
- return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
-}
-
-func trace(args ...interface{}) func() {
- pargs := append([]interface{}{"+++"}, args...)
- fmt.Println(pargs...)
- pargs = append([]interface{}{"---"}, args...)
- return func() { fmt.Println(pargs...) }
-}
-
-// Ensure that the tokens queue contains at least one token which can be
-// returned to the Parser.
-func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
- // While we need more tokens to fetch, do it.
- for {
- // Check if we really need to fetch more tokens.
- need_more_tokens := false
-
- if parser.tokens_head == len(parser.tokens) {
- // Queue is empty.
- need_more_tokens = true
- } else {
- // Check if any potential simple key may occupy the head position.
- if !yaml_parser_stale_simple_keys(parser) {
- return false
- }
-
- for i := range parser.simple_keys {
- simple_key := &parser.simple_keys[i]
- if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
- need_more_tokens = true
- break
- }
- }
- }
-
- // We are finished.
- if !need_more_tokens {
- break
- }
- // Fetch the next token.
- if !yaml_parser_fetch_next_token(parser) {
- return false
- }
- }
-
- parser.token_available = true
- return true
-}
-
-// The dispatcher for token fetchers.
-func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
- // Ensure that the buffer is initialized.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- // Check if we just started scanning. Fetch STREAM-START then.
- if !parser.stream_start_produced {
- return yaml_parser_fetch_stream_start(parser)
- }
-
- // Eat whitespaces and comments until we reach the next token.
- if !yaml_parser_scan_to_next_token(parser) {
- return false
- }
-
- // Remove obsolete potential simple keys.
- if !yaml_parser_stale_simple_keys(parser) {
- return false
- }
-
- // Check the indentation level against the current column.
- if !yaml_parser_unroll_indent(parser, parser.mark.column) {
- return false
- }
-
- // Ensure that the buffer contains at least 4 characters. 4 is the length
- // of the longest indicators ('--- ' and '... ').
- if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
- return false
- }
-
- // Is it the end of the stream?
- if is_z(parser.buffer, parser.buffer_pos) {
- return yaml_parser_fetch_stream_end(parser)
- }
-
- // Is it a directive?
- if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
- return yaml_parser_fetch_directive(parser)
- }
-
- buf := parser.buffer
- pos := parser.buffer_pos
-
- // Is it the document start indicator?
- if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
- return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
- }
-
- // Is it the document end indicator?
- if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
- return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
- }
-
- // Is it the flow sequence start indicator?
- if buf[pos] == '[' {
- return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
- }
-
- // Is it the flow mapping start indicator?
- if parser.buffer[parser.buffer_pos] == '{' {
- return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
- }
-
- // Is it the flow sequence end indicator?
- if parser.buffer[parser.buffer_pos] == ']' {
- return yaml_parser_fetch_flow_collection_end(parser,
- yaml_FLOW_SEQUENCE_END_TOKEN)
- }
-
- // Is it the flow mapping end indicator?
- if parser.buffer[parser.buffer_pos] == '}' {
- return yaml_parser_fetch_flow_collection_end(parser,
- yaml_FLOW_MAPPING_END_TOKEN)
- }
-
- // Is it the flow entry indicator?
- if parser.buffer[parser.buffer_pos] == ',' {
- return yaml_parser_fetch_flow_entry(parser)
- }
-
- // Is it the block entry indicator?
- if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
- return yaml_parser_fetch_block_entry(parser)
- }
-
- // Is it the key indicator?
- if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
- return yaml_parser_fetch_key(parser)
- }
-
- // Is it the value indicator?
- if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
- return yaml_parser_fetch_value(parser)
- }
-
- // Is it an alias?
- if parser.buffer[parser.buffer_pos] == '*' {
- return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
- }
-
- // Is it an anchor?
- if parser.buffer[parser.buffer_pos] == '&' {
- return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
- }
-
- // Is it a tag?
- if parser.buffer[parser.buffer_pos] == '!' {
- return yaml_parser_fetch_tag(parser)
- }
-
- // Is it a literal scalar?
- if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
- return yaml_parser_fetch_block_scalar(parser, true)
- }
-
- // Is it a folded scalar?
- if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
- return yaml_parser_fetch_block_scalar(parser, false)
- }
-
- // Is it a single-quoted scalar?
- if parser.buffer[parser.buffer_pos] == '\'' {
- return yaml_parser_fetch_flow_scalar(parser, true)
- }
-
- // Is it a double-quoted scalar?
- if parser.buffer[parser.buffer_pos] == '"' {
- return yaml_parser_fetch_flow_scalar(parser, false)
- }
-
- // Is it a plain scalar?
- //
- // A plain scalar may start with any non-blank characters except
- //
- // '-', '?', ':', ',', '[', ']', '{', '}',
- // '#', '&', '*', '!', '|', '>', '\'', '\"',
- // '%', '@', '`'.
- //
- // In the block context (and, for the '-' indicator, in the flow context
- // too), it may also start with the characters
- //
- // '-', '?', ':'
- //
- // if it is followed by a non-space character.
- //
- // The last rule is more restrictive than the specification requires.
- // [Go] Make this logic more reasonable.
- //switch parser.buffer[parser.buffer_pos] {
- //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
- //}
- if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
- parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
- parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
- parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
- parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
- parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
- parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
- parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
- parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
- parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
- (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
- (parser.flow_level == 0 &&
- (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
- !is_blankz(parser.buffer, parser.buffer_pos+1)) {
- return yaml_parser_fetch_plain_scalar(parser)
- }
-
- // If we don't determine the token type so far, it is an error.
- return yaml_parser_set_scanner_error(parser,
- "while scanning for the next token", parser.mark,
- "found character that cannot start any token")
-}
-
-// Check the list of potential simple keys and remove the positions that
-// cannot contain simple keys anymore.
-func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
- // Check for a potential simple key for each flow level.
- for i := range parser.simple_keys {
- simple_key := &parser.simple_keys[i]
-
- // The specification requires that a simple key
- //
- // - is limited to a single line,
- // - is shorter than 1024 characters.
- if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
-
- // Check if the potential simple key to be removed is required.
- if simple_key.required {
- return yaml_parser_set_scanner_error(parser,
- "while scanning a simple key", simple_key.mark,
- "could not find expected ':'")
- }
- simple_key.possible = false
- }
- }
- return true
-}
-
-// Check if a simple key may start at the current position and add it if
-// needed.
-func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
- // A simple key is required at the current position if the scanner is in
- // the block context and the current column coincides with the indentation
- // level.
-
- required := parser.flow_level == 0 && parser.indent == parser.mark.column
-
- // A simple key is required only when it is the first token in the current
- // line. Therefore it is always allowed. But we add a check anyway.
- if required && !parser.simple_key_allowed {
- panic("should not happen")
- }
-
- //
- // If the current position may start a simple key, save it.
- //
- if parser.simple_key_allowed {
- simple_key := yaml_simple_key_t{
- possible: true,
- required: required,
- token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
- }
- simple_key.mark = parser.mark
-
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
- parser.simple_keys[len(parser.simple_keys)-1] = simple_key
- }
- return true
-}
-
-// Remove a potential simple key at the current flow level.
-func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
- i := len(parser.simple_keys) - 1
- if parser.simple_keys[i].possible {
- // If the key is required, it is an error.
- if parser.simple_keys[i].required {
- return yaml_parser_set_scanner_error(parser,
- "while scanning a simple key", parser.simple_keys[i].mark,
- "could not find expected ':'")
- }
- }
- // Remove the key from the stack.
- parser.simple_keys[i].possible = false
- return true
-}
-
-// Increase the flow level and resize the simple key list if needed.
-func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
- // Reset the simple key on the next level.
- parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
-
- // Increase the flow level.
- parser.flow_level++
- return true
-}
-
-// Decrease the flow level.
-func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
- if parser.flow_level > 0 {
- parser.flow_level--
- parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
- }
- return true
-}
-
-// Push the current indentation level to the stack and set the new level
-// the current column is greater than the indentation level. In this case,
-// append or insert the specified token into the token queue.
-func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
- // In the flow context, do nothing.
- if parser.flow_level > 0 {
- return true
- }
-
- if parser.indent < column {
- // Push the current indentation level to the stack and set the new
- // indentation level.
- parser.indents = append(parser.indents, parser.indent)
- parser.indent = column
-
- // Create a token and insert it into the queue.
- token := yaml_token_t{
- typ: typ,
- start_mark: mark,
- end_mark: mark,
- }
- if number > -1 {
- number -= parser.tokens_parsed
- }
- yaml_insert_token(parser, number, &token)
- }
- return true
-}
-
-// Pop indentation levels from the indents stack until the current level
-// becomes less or equal to the column. For each indentation level, append
-// the BLOCK-END token.
-func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
- // In the flow context, do nothing.
- if parser.flow_level > 0 {
- return true
- }
-
- // Loop through the indentation levels in the stack.
- for parser.indent > column {
- // Create a token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_BLOCK_END_TOKEN,
- start_mark: parser.mark,
- end_mark: parser.mark,
- }
- yaml_insert_token(parser, -1, &token)
-
- // Pop the indentation level.
- parser.indent = parser.indents[len(parser.indents)-1]
- parser.indents = parser.indents[:len(parser.indents)-1]
- }
- return true
-}
-
-// Initialize the scanner and produce the STREAM-START token.
-func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
-
- // Set the initial indentation.
- parser.indent = -1
-
- // Initialize the simple key stack.
- parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
-
- // A simple key is allowed at the beginning of the stream.
- parser.simple_key_allowed = true
-
- // We have started.
- parser.stream_start_produced = true
-
- // Create the STREAM-START token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_STREAM_START_TOKEN,
- start_mark: parser.mark,
- end_mark: parser.mark,
- encoding: parser.encoding,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the STREAM-END token and shut down the scanner.
-func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
-
- // Force new line.
- if parser.mark.column != 0 {
- parser.mark.column = 0
- parser.mark.line++
- }
-
- // Reset the indentation level.
- if !yaml_parser_unroll_indent(parser, -1) {
- return false
- }
-
- // Reset simple keys.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- parser.simple_key_allowed = false
-
- // Create the STREAM-END token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_STREAM_END_TOKEN,
- start_mark: parser.mark,
- end_mark: parser.mark,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
-func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
- // Reset the indentation level.
- if !yaml_parser_unroll_indent(parser, -1) {
- return false
- }
-
- // Reset simple keys.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- parser.simple_key_allowed = false
-
- // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
- token := yaml_token_t{}
- if !yaml_parser_scan_directive(parser, &token) {
- return false
- }
- // Append the token to the queue.
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the DOCUMENT-START or DOCUMENT-END token.
-func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
- // Reset the indentation level.
- if !yaml_parser_unroll_indent(parser, -1) {
- return false
- }
-
- // Reset simple keys.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- parser.simple_key_allowed = false
-
- // Consume the token.
- start_mark := parser.mark
-
- skip(parser)
- skip(parser)
- skip(parser)
-
- end_mark := parser.mark
-
- // Create the DOCUMENT-START or DOCUMENT-END token.
- token := yaml_token_t{
- typ: typ,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- // Append the token to the queue.
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
-func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
- // The indicators '[' and '{' may start a simple key.
- if !yaml_parser_save_simple_key(parser) {
- return false
- }
-
- // Increase the flow level.
- if !yaml_parser_increase_flow_level(parser) {
- return false
- }
-
- // A simple key may follow the indicators '[' and '{'.
- parser.simple_key_allowed = true
-
- // Consume the token.
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
- token := yaml_token_t{
- typ: typ,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- // Append the token to the queue.
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
-func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
- // Reset any potential simple key on the current flow level.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- // Decrease the flow level.
- if !yaml_parser_decrease_flow_level(parser) {
- return false
- }
-
- // No simple keys after the indicators ']' and '}'.
- parser.simple_key_allowed = false
-
- // Consume the token.
-
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
- token := yaml_token_t{
- typ: typ,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- // Append the token to the queue.
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the FLOW-ENTRY token.
-func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
- // Reset any potential simple keys on the current flow level.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- // Simple keys are allowed after ','.
- parser.simple_key_allowed = true
-
- // Consume the token.
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the FLOW-ENTRY token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_FLOW_ENTRY_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the BLOCK-ENTRY token.
-func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
- // Check if the scanner is in the block context.
- if parser.flow_level == 0 {
- // Check if we are allowed to start a new entry.
- if !parser.simple_key_allowed {
- return yaml_parser_set_scanner_error(parser, "", parser.mark,
- "block sequence entries are not allowed in this context")
- }
- // Add the BLOCK-SEQUENCE-START token if needed.
- if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
- return false
- }
- } else {
- // It is an error for the '-' indicator to occur in the flow context,
- // but we let the Parser detect and report about it because the Parser
- // is able to point to the context.
- }
-
- // Reset any potential simple keys on the current flow level.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- // Simple keys are allowed after '-'.
- parser.simple_key_allowed = true
-
- // Consume the token.
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the BLOCK-ENTRY token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_BLOCK_ENTRY_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the KEY token.
-func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
-
- // In the block context, additional checks are required.
- if parser.flow_level == 0 {
- // Check if we are allowed to start a new key (not nessesary simple).
- if !parser.simple_key_allowed {
- return yaml_parser_set_scanner_error(parser, "", parser.mark,
- "mapping keys are not allowed in this context")
- }
- // Add the BLOCK-MAPPING-START token if needed.
- if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
- return false
- }
- }
-
- // Reset any potential simple keys on the current flow level.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- // Simple keys are allowed after '?' in the block context.
- parser.simple_key_allowed = parser.flow_level == 0
-
- // Consume the token.
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the KEY token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_KEY_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the VALUE token.
-func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
-
- simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
-
- // Have we found a simple key?
- if simple_key.possible {
- // Create the KEY token and insert it into the queue.
- token := yaml_token_t{
- typ: yaml_KEY_TOKEN,
- start_mark: simple_key.mark,
- end_mark: simple_key.mark,
- }
- yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
-
- // In the block context, we may need to add the BLOCK-MAPPING-START token.
- if !yaml_parser_roll_indent(parser, simple_key.mark.column,
- simple_key.token_number,
- yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
- return false
- }
-
- // Remove the simple key.
- simple_key.possible = false
-
- // A simple key cannot follow another simple key.
- parser.simple_key_allowed = false
-
- } else {
- // The ':' indicator follows a complex key.
-
- // In the block context, extra checks are required.
- if parser.flow_level == 0 {
-
- // Check if we are allowed to start a complex value.
- if !parser.simple_key_allowed {
- return yaml_parser_set_scanner_error(parser, "", parser.mark,
- "mapping values are not allowed in this context")
- }
-
- // Add the BLOCK-MAPPING-START token if needed.
- if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
- return false
- }
- }
-
- // Simple keys after ':' are allowed in the block context.
- parser.simple_key_allowed = parser.flow_level == 0
- }
-
- // Consume the token.
- start_mark := parser.mark
- skip(parser)
- end_mark := parser.mark
-
- // Create the VALUE token and append it to the queue.
- token := yaml_token_t{
- typ: yaml_VALUE_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the ALIAS or ANCHOR token.
-func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
- // An anchor or an alias could be a simple key.
- if !yaml_parser_save_simple_key(parser) {
- return false
- }
-
- // A simple key cannot follow an anchor or an alias.
- parser.simple_key_allowed = false
-
- // Create the ALIAS or ANCHOR token and append it to the queue.
- var token yaml_token_t
- if !yaml_parser_scan_anchor(parser, &token, typ) {
- return false
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the TAG token.
-func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
- // A tag could be a simple key.
- if !yaml_parser_save_simple_key(parser) {
- return false
- }
-
- // A simple key cannot follow a tag.
- parser.simple_key_allowed = false
-
- // Create the TAG token and append it to the queue.
- var token yaml_token_t
- if !yaml_parser_scan_tag(parser, &token) {
- return false
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
-func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
- // Remove any potential simple keys.
- if !yaml_parser_remove_simple_key(parser) {
- return false
- }
-
- // A simple key may follow a block scalar.
- parser.simple_key_allowed = true
-
- // Create the SCALAR token and append it to the queue.
- var token yaml_token_t
- if !yaml_parser_scan_block_scalar(parser, &token, literal) {
- return false
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
-func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
- // A plain scalar could be a simple key.
- if !yaml_parser_save_simple_key(parser) {
- return false
- }
-
- // A simple key cannot follow a flow scalar.
- parser.simple_key_allowed = false
-
- // Create the SCALAR token and append it to the queue.
- var token yaml_token_t
- if !yaml_parser_scan_flow_scalar(parser, &token, single) {
- return false
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Produce the SCALAR(...,plain) token.
-func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
- // A plain scalar could be a simple key.
- if !yaml_parser_save_simple_key(parser) {
- return false
- }
-
- // A simple key cannot follow a flow scalar.
- parser.simple_key_allowed = false
-
- // Create the SCALAR token and append it to the queue.
- var token yaml_token_t
- if !yaml_parser_scan_plain_scalar(parser, &token) {
- return false
- }
- yaml_insert_token(parser, -1, &token)
- return true
-}
-
-// Eat whitespaces and comments until the next token is found.
-func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
-
- // Until the next token is not found.
- for {
- // Allow the BOM mark to start a line.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
- skip(parser)
- }
-
- // Eat whitespaces.
- // Tabs are allowed:
- // - in the flow context
- // - in the block context, but not at the beginning of the line or
- // after '-', '?', or ':' (complex value).
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Eat a comment until a line break.
- if parser.buffer[parser.buffer_pos] == '#' {
- for !is_breakz(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
- }
-
- // If it is a line break, eat it.
- if is_break(parser.buffer, parser.buffer_pos) {
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- skip_line(parser)
-
- // In the block context, a new line may start a simple key.
- if parser.flow_level == 0 {
- parser.simple_key_allowed = true
- }
- } else {
- break // We have found a token.
- }
- }
-
- return true
-}
-
-// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
-//
-// Scope:
-// %YAML 1.1 # a comment \n
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// %TAG !yaml! tag:yaml.org,2002: \n
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
- // Eat '%'.
- start_mark := parser.mark
- skip(parser)
-
- // Scan the directive name.
- var name []byte
- if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
- return false
- }
-
- // Is it a YAML directive?
- if bytes.Equal(name, []byte("YAML")) {
- // Scan the VERSION directive value.
- var major, minor int8
- if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
- return false
- }
- end_mark := parser.mark
-
- // Create a VERSION-DIRECTIVE token.
- *token = yaml_token_t{
- typ: yaml_VERSION_DIRECTIVE_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- major: major,
- minor: minor,
- }
-
- // Is it a TAG directive?
- } else if bytes.Equal(name, []byte("TAG")) {
- // Scan the TAG directive value.
- var handle, prefix []byte
- if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
- return false
- }
- end_mark := parser.mark
-
- // Create a TAG-DIRECTIVE token.
- *token = yaml_token_t{
- typ: yaml_TAG_DIRECTIVE_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- value: handle,
- prefix: prefix,
- }
-
- // Unknown directive.
- } else {
- yaml_parser_set_scanner_error(parser, "while scanning a directive",
- start_mark, "found uknown directive name")
- return false
- }
-
- // Eat the rest of the line including any comments.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for is_blank(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- if parser.buffer[parser.buffer_pos] == '#' {
- for !is_breakz(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
- }
-
- // Check if we are at the end of the line.
- if !is_breakz(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a directive",
- start_mark, "did not find expected comment or line break")
- return false
- }
-
- // Eat a line break.
- if is_break(parser.buffer, parser.buffer_pos) {
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- skip_line(parser)
- }
-
- return true
-}
-
-// Scan the directive name.
-//
-// Scope:
-// %YAML 1.1 # a comment \n
-// ^^^^
-// %TAG !yaml! tag:yaml.org,2002: \n
-// ^^^
-//
-func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
- // Consume the directive name.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- var s []byte
- for is_alpha(parser.buffer, parser.buffer_pos) {
- s = read(parser, s)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Check if the name is empty.
- if len(s) == 0 {
- yaml_parser_set_scanner_error(parser, "while scanning a directive",
- start_mark, "could not find expected directive name")
- return false
- }
-
- // Check for an blank character after the name.
- if !is_blankz(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a directive",
- start_mark, "found unexpected non-alphabetical character")
- return false
- }
- *name = s
- return true
-}
-
-// Scan the value of VERSION-DIRECTIVE.
-//
-// Scope:
-// %YAML 1.1 # a comment \n
-// ^^^^^^
-func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
- // Eat whitespaces.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- for is_blank(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Consume the major version number.
- if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
- return false
- }
-
- // Eat '.'.
- if parser.buffer[parser.buffer_pos] != '.' {
- return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
- start_mark, "did not find expected digit or '.' character")
- }
-
- skip(parser)
-
- // Consume the minor version number.
- if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
- return false
- }
- return true
-}
-
-const max_number_length = 2
-
-// Scan the version number of VERSION-DIRECTIVE.
-//
-// Scope:
-// %YAML 1.1 # a comment \n
-// ^
-// %YAML 1.1 # a comment \n
-// ^
-func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
-
- // Repeat while the next character is digit.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- var value, length int8
- for is_digit(parser.buffer, parser.buffer_pos) {
- // Check if the number is too long.
- length++
- if length > max_number_length {
- return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
- start_mark, "found extremely long version number")
- }
- value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Check if the number was present.
- if length == 0 {
- return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
- start_mark, "did not find expected version number")
- }
- *number = value
- return true
-}
-
-// Scan the value of a TAG-DIRECTIVE token.
-//
-// Scope:
-// %TAG !yaml! tag:yaml.org,2002: \n
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
- var handle_value, prefix_value []byte
-
- // Eat whitespaces.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for is_blank(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Scan a handle.
- if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
- return false
- }
-
- // Expect a whitespace.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if !is_blank(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
- start_mark, "did not find expected whitespace")
- return false
- }
-
- // Eat whitespaces.
- for is_blank(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Scan a prefix.
- if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
- return false
- }
-
- // Expect a whitespace or line break.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if !is_blankz(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
- start_mark, "did not find expected whitespace or line break")
- return false
- }
-
- *handle = handle_value
- *prefix = prefix_value
- return true
-}
-
-func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
- var s []byte
-
- // Eat the indicator character.
- start_mark := parser.mark
- skip(parser)
-
- // Consume the value.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for is_alpha(parser.buffer, parser.buffer_pos) {
- s = read(parser, s)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- end_mark := parser.mark
-
- /*
- * Check if length of the anchor is greater than 0 and it is followed by
- * a whitespace character or one of the indicators:
- *
- * '?', ':', ',', ']', '}', '%', '@', '`'.
- */
-
- if len(s) == 0 ||
- !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
- parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
- parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
- parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
- parser.buffer[parser.buffer_pos] == '`') {
- context := "while scanning an alias"
- if typ == yaml_ANCHOR_TOKEN {
- context = "while scanning an anchor"
- }
- yaml_parser_set_scanner_error(parser, context, start_mark,
- "did not find expected alphabetic or numeric character")
- return false
- }
-
- // Create a token.
- *token = yaml_token_t{
- typ: typ,
- start_mark: start_mark,
- end_mark: end_mark,
- value: s,
- }
-
- return true
-}
-
-/*
- * Scan a TAG token.
- */
-
-func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
- var handle, suffix []byte
-
- start_mark := parser.mark
-
- // Check if the tag is in the canonical form.
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
-
- if parser.buffer[parser.buffer_pos+1] == '<' {
- // Keep the handle as ''
-
- // Eat '!<'
- skip(parser)
- skip(parser)
-
- // Consume the tag value.
- if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
- return false
- }
-
- // Check for '>' and eat it.
- if parser.buffer[parser.buffer_pos] != '>' {
- yaml_parser_set_scanner_error(parser, "while scanning a tag",
- start_mark, "did not find the expected '>'")
- return false
- }
-
- skip(parser)
- } else {
- // The tag has either the '!suffix' or the '!handle!suffix' form.
-
- // First, try to scan a handle.
- if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
- return false
- }
-
- // Check if it is, indeed, handle.
- if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
- // Scan the suffix now.
- if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
- return false
- }
- } else {
- // It wasn't a handle after all. Scan the rest of the tag.
- if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
- return false
- }
-
- // Set the handle to '!'.
- handle = []byte{'!'}
-
- // A special case: the '!' tag. Set the handle to '' and the
- // suffix to '!'.
- if len(suffix) == 0 {
- handle, suffix = suffix, handle
- }
- }
- }
-
- // Check the character which ends the tag.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if !is_blankz(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a tag",
- start_mark, "did not find expected whitespace or line break")
- return false
- }
-
- end_mark := parser.mark
-
- // Create a token.
- *token = yaml_token_t{
- typ: yaml_TAG_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- value: handle,
- suffix: suffix,
- }
- return true
-}
-
-// Scan a tag handle.
-func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
- // Check the initial '!' character.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if parser.buffer[parser.buffer_pos] != '!' {
- yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "did not find expected '!'")
- return false
- }
-
- var s []byte
-
- // Copy the '!' character.
- s = read(parser, s)
-
- // Copy all subsequent alphabetical and numerical characters.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- for is_alpha(parser.buffer, parser.buffer_pos) {
- s = read(parser, s)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Check if the trailing character is '!' and copy it.
- if parser.buffer[parser.buffer_pos] == '!' {
- s = read(parser, s)
- } else {
- // It's either the '!' tag or not really a tag handle. If it's a %TAG
- // directive, it's an error. If it's a tag token, it must be a part of URI.
- if directive && !(s[0] == '!' && s[1] == 0) {
- yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "did not find expected '!'")
- return false
- }
- }
-
- *handle = s
- return true
-}
-
-// Scan a tag.
-func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
- //size_t length = head ? strlen((char *)head) : 0
- var s []byte
-
- // Copy the head if needed.
- //
- // Note that we don't copy the leading '!' character.
- if len(head) > 1 {
- s = append(s, head[1:]...)
- }
-
- // Scan the tag.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- // The set of characters that may appear in URI is as follows:
- //
- // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
- // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
- // '%'.
- // [Go] Convert this into more reasonable logic.
- for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
- parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
- parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
- parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
- parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
- parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
- parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
- parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
- parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
- parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
- parser.buffer[parser.buffer_pos] == '%' {
- // Check if it is a URI-escape sequence.
- if parser.buffer[parser.buffer_pos] == '%' {
- if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
- return false
- }
- } else {
- s = read(parser, s)
- }
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Check if the tag is non-empty.
- if len(s) == 0 {
- yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "did not find expected tag URI")
- return false
- }
- *uri = s
- return true
-}
-
-// Decode an URI-escape sequence corresponding to a single UTF-8 character.
-func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
-
- // Decode the required number of characters.
- w := 1024
- for w > 0 {
- // Check for a URI-escaped octet.
- if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
- return false
- }
-
- if !(parser.buffer[parser.buffer_pos] == '%' &&
- is_hex(parser.buffer, parser.buffer_pos+1) &&
- is_hex(parser.buffer, parser.buffer_pos+2)) {
- return yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "did not find URI escaped octet")
- }
-
- // Get the octet.
- octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
-
- // If it is the leading octet, determine the length of the UTF-8 sequence.
- if w == 1024 {
- w = width(octet)
- if w == 0 {
- return yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "found an incorrect leading UTF-8 octet")
- }
- } else {
- // Check if the trailing octet is correct.
- if octet&0xC0 != 0x80 {
- return yaml_parser_set_scanner_tag_error(parser, directive,
- start_mark, "found an incorrect trailing UTF-8 octet")
- }
- }
-
- // Copy the octet and move the pointers.
- *s = append(*s, octet)
- skip(parser)
- skip(parser)
- skip(parser)
- w--
- }
- return true
-}
-
-// Scan a block scalar.
-func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
- // Eat the indicator '|' or '>'.
- start_mark := parser.mark
- skip(parser)
-
- // Scan the additional block scalar indicators.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- // Check for a chomping indicator.
- var chomping, increment int
- if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
- // Set the chomping method and eat the indicator.
- if parser.buffer[parser.buffer_pos] == '+' {
- chomping = +1
- } else {
- chomping = -1
- }
- skip(parser)
-
- // Check for an indentation indicator.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if is_digit(parser.buffer, parser.buffer_pos) {
- // Check that the indentation is greater than 0.
- if parser.buffer[parser.buffer_pos] == '0' {
- yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found an indentation indicator equal to 0")
- return false
- }
-
- // Get the indentation level and eat the indicator.
- increment = as_digit(parser.buffer, parser.buffer_pos)
- skip(parser)
- }
-
- } else if is_digit(parser.buffer, parser.buffer_pos) {
- // Do the same as above, but in the opposite order.
-
- if parser.buffer[parser.buffer_pos] == '0' {
- yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found an indentation indicator equal to 0")
- return false
- }
- increment = as_digit(parser.buffer, parser.buffer_pos)
- skip(parser)
-
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
- if parser.buffer[parser.buffer_pos] == '+' {
- chomping = +1
- } else {
- chomping = -1
- }
- skip(parser)
- }
- }
-
- // Eat whitespaces and comments to the end of the line.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- for is_blank(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
- if parser.buffer[parser.buffer_pos] == '#' {
- for !is_breakz(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
- }
-
- // Check if we are at the end of the line.
- if !is_breakz(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "did not find expected comment or line break")
- return false
- }
-
- // Eat a line break.
- if is_break(parser.buffer, parser.buffer_pos) {
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- skip_line(parser)
- }
-
- end_mark := parser.mark
-
- // Set the indentation level if it was specified.
- var indent int
- if increment > 0 {
- if parser.indent >= 0 {
- indent = parser.indent + increment
- } else {
- indent = increment
- }
- }
-
- // Scan the leading line breaks and determine the indentation level if needed.
- var s, leading_break, trailing_breaks []byte
- if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
- return false
- }
-
- // Scan the block scalar content.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- var leading_blank, trailing_blank bool
- for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
- // We are at the beginning of a non-empty line.
-
- // Is it a trailing whitespace?
- trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
-
- // Check if we need to fold the leading line break.
- if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
- // Do we need to join the lines by space?
- if len(trailing_breaks) == 0 {
- s = append(s, ' ')
- }
- } else {
- s = append(s, leading_break...)
- }
- leading_break = leading_break[:0]
-
- // Append the remaining line breaks.
- s = append(s, trailing_breaks...)
- trailing_breaks = trailing_breaks[:0]
-
- // Is it a leading whitespace?
- leading_blank = is_blank(parser.buffer, parser.buffer_pos)
-
- // Consume the current line.
- for !is_breakz(parser.buffer, parser.buffer_pos) {
- s = read(parser, s)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Consume the line break.
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
-
- leading_break = read_line(parser, leading_break)
-
- // Eat the following indentation spaces and line breaks.
- if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
- return false
- }
- }
-
- // Chomp the tail.
- if chomping != -1 {
- s = append(s, leading_break...)
- }
- if chomping == 1 {
- s = append(s, trailing_breaks...)
- }
-
- // Create a token.
- *token = yaml_token_t{
- typ: yaml_SCALAR_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- value: s,
- style: yaml_LITERAL_SCALAR_STYLE,
- }
- if !literal {
- token.style = yaml_FOLDED_SCALAR_STYLE
- }
- return true
-}
-
-// Scan indentation spaces and line breaks for a block scalar. Determine the
-// indentation level if needed.
-func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
- *end_mark = parser.mark
-
- // Eat the indentation spaces and line breaks.
- max_indent := 0
- for {
- // Eat the indentation spaces.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
- skip(parser)
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
- if parser.mark.column > max_indent {
- max_indent = parser.mark.column
- }
-
- // Check for a tab character messing the indentation.
- if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
- return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found a tab character where an indentation space is expected")
- }
-
- // Have we found a non-empty line?
- if !is_break(parser.buffer, parser.buffer_pos) {
- break
- }
-
- // Consume the line break.
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- // [Go] Should really be returning breaks instead.
- *breaks = read_line(parser, *breaks)
- *end_mark = parser.mark
- }
-
- // Determine the indentation level if needed.
- if *indent == 0 {
- *indent = max_indent
- if *indent < parser.indent+1 {
- *indent = parser.indent + 1
- }
- if *indent < 1 {
- *indent = 1
- }
- }
- return true
-}
-
-// Scan a quoted scalar.
-func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
- // Eat the left quote.
- start_mark := parser.mark
- skip(parser)
-
- // Consume the content of the quoted scalar.
- var s, leading_break, trailing_breaks, whitespaces []byte
- for {
- // Check that there are no document indicators at the beginning of the line.
- if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
- return false
- }
-
- if parser.mark.column == 0 &&
- ((parser.buffer[parser.buffer_pos+0] == '-' &&
- parser.buffer[parser.buffer_pos+1] == '-' &&
- parser.buffer[parser.buffer_pos+2] == '-') ||
- (parser.buffer[parser.buffer_pos+0] == '.' &&
- parser.buffer[parser.buffer_pos+1] == '.' &&
- parser.buffer[parser.buffer_pos+2] == '.')) &&
- is_blankz(parser.buffer, parser.buffer_pos+3) {
- yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
- start_mark, "found unexpected document indicator")
- return false
- }
-
- // Check for EOF.
- if is_z(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
- start_mark, "found unexpected end of stream")
- return false
- }
-
- // Consume non-blank characters.
- leading_blanks := false
- for !is_blankz(parser.buffer, parser.buffer_pos) {
- if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
- // Is is an escaped single quote.
- s = append(s, '\'')
- skip(parser)
- skip(parser)
-
- } else if single && parser.buffer[parser.buffer_pos] == '\'' {
- // It is a right single quote.
- break
- } else if !single && parser.buffer[parser.buffer_pos] == '"' {
- // It is a right double quote.
- break
-
- } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
- // It is an escaped line break.
- if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
- return false
- }
- skip(parser)
- skip_line(parser)
- leading_blanks = true
- break
-
- } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
- // It is an escape sequence.
- code_length := 0
-
- // Check the escape character.
- switch parser.buffer[parser.buffer_pos+1] {
- case '0':
- s = append(s, 0)
- case 'a':
- s = append(s, '\x07')
- case 'b':
- s = append(s, '\x08')
- case 't', '\t':
- s = append(s, '\x09')
- case 'n':
- s = append(s, '\x0A')
- case 'v':
- s = append(s, '\x0B')
- case 'f':
- s = append(s, '\x0C')
- case 'r':
- s = append(s, '\x0D')
- case 'e':
- s = append(s, '\x1B')
- case ' ':
- s = append(s, '\x20')
- case '"':
- s = append(s, '"')
- case '\'':
- s = append(s, '\'')
- case '\\':
- s = append(s, '\\')
- case 'N': // NEL (#x85)
- s = append(s, '\xC2')
- s = append(s, '\x85')
- case '_': // #xA0
- s = append(s, '\xC2')
- s = append(s, '\xA0')
- case 'L': // LS (#x2028)
- s = append(s, '\xE2')
- s = append(s, '\x80')
- s = append(s, '\xA8')
- case 'P': // PS (#x2029)
- s = append(s, '\xE2')
- s = append(s, '\x80')
- s = append(s, '\xA9')
- case 'x':
- code_length = 2
- case 'u':
- code_length = 4
- case 'U':
- code_length = 8
- default:
- yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
- start_mark, "found unknown escape character")
- return false
- }
-
- skip(parser)
- skip(parser)
-
- // Consume an arbitrary escape code.
- if code_length > 0 {
- var value int
-
- // Scan the character value.
- if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
- return false
- }
- for k := 0; k < code_length; k++ {
- if !is_hex(parser.buffer, parser.buffer_pos+k) {
- yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
- start_mark, "did not find expected hexdecimal number")
- return false
- }
- value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
- }
-
- // Check the value and write the character.
- if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
- yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
- start_mark, "found invalid Unicode character escape code")
- return false
- }
- if value <= 0x7F {
- s = append(s, byte(value))
- } else if value <= 0x7FF {
- s = append(s, byte(0xC0+(value>>6)))
- s = append(s, byte(0x80+(value&0x3F)))
- } else if value <= 0xFFFF {
- s = append(s, byte(0xE0+(value>>12)))
- s = append(s, byte(0x80+((value>>6)&0x3F)))
- s = append(s, byte(0x80+(value&0x3F)))
- } else {
- s = append(s, byte(0xF0+(value>>18)))
- s = append(s, byte(0x80+((value>>12)&0x3F)))
- s = append(s, byte(0x80+((value>>6)&0x3F)))
- s = append(s, byte(0x80+(value&0x3F)))
- }
-
- // Advance the pointer.
- for k := 0; k < code_length; k++ {
- skip(parser)
- }
- }
- } else {
- // It is a non-escaped non-blank character.
- s = read(parser, s)
- }
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- }
-
- // Check if we are at the end of the scalar.
- if single {
- if parser.buffer[parser.buffer_pos] == '\'' {
- break
- }
- } else {
- if parser.buffer[parser.buffer_pos] == '"' {
- break
- }
- }
-
- // Consume blank characters.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
- if is_blank(parser.buffer, parser.buffer_pos) {
- // Consume a space or a tab character.
- if !leading_blanks {
- whitespaces = read(parser, whitespaces)
- } else {
- skip(parser)
- }
- } else {
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
-
- // Check if it is a first line break.
- if !leading_blanks {
- whitespaces = whitespaces[:0]
- leading_break = read_line(parser, leading_break)
- leading_blanks = true
- } else {
- trailing_breaks = read_line(parser, trailing_breaks)
- }
- }
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Join the whitespaces or fold line breaks.
- if leading_blanks {
- // Do we need to fold line breaks?
- if len(leading_break) > 0 && leading_break[0] == '\n' {
- if len(trailing_breaks) == 0 {
- s = append(s, ' ')
- } else {
- s = append(s, trailing_breaks...)
- }
- } else {
- s = append(s, leading_break...)
- s = append(s, trailing_breaks...)
- }
- trailing_breaks = trailing_breaks[:0]
- leading_break = leading_break[:0]
- } else {
- s = append(s, whitespaces...)
- whitespaces = whitespaces[:0]
- }
- }
-
- // Eat the right quote.
- skip(parser)
- end_mark := parser.mark
-
- // Create a token.
- *token = yaml_token_t{
- typ: yaml_SCALAR_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- value: s,
- style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
- }
- if !single {
- token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
- }
- return true
-}
-
-// Scan a plain scalar.
-func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
-
- var s, leading_break, trailing_breaks, whitespaces []byte
- var leading_blanks bool
- var indent = parser.indent + 1
-
- start_mark := parser.mark
- end_mark := parser.mark
-
- // Consume the content of the plain scalar.
- for {
- // Check for a document indicator.
- if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
- return false
- }
- if parser.mark.column == 0 &&
- ((parser.buffer[parser.buffer_pos+0] == '-' &&
- parser.buffer[parser.buffer_pos+1] == '-' &&
- parser.buffer[parser.buffer_pos+2] == '-') ||
- (parser.buffer[parser.buffer_pos+0] == '.' &&
- parser.buffer[parser.buffer_pos+1] == '.' &&
- parser.buffer[parser.buffer_pos+2] == '.')) &&
- is_blankz(parser.buffer, parser.buffer_pos+3) {
- break
- }
-
- // Check for a comment.
- if parser.buffer[parser.buffer_pos] == '#' {
- break
- }
-
- // Consume non-blank characters.
- for !is_blankz(parser.buffer, parser.buffer_pos) {
-
- // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
- if parser.flow_level > 0 &&
- parser.buffer[parser.buffer_pos] == ':' &&
- !is_blankz(parser.buffer, parser.buffer_pos+1) {
- yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
- start_mark, "found unexpected ':'")
- return false
- }
-
- // Check for indicators that may end a plain scalar.
- if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
- (parser.flow_level > 0 &&
- (parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
- parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
- parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
- parser.buffer[parser.buffer_pos] == '}')) {
- break
- }
-
- // Check if we need to join whitespaces and breaks.
- if leading_blanks || len(whitespaces) > 0 {
- if leading_blanks {
- // Do we need to fold line breaks?
- if leading_break[0] == '\n' {
- if len(trailing_breaks) == 0 {
- s = append(s, ' ')
- } else {
- s = append(s, trailing_breaks...)
- }
- } else {
- s = append(s, leading_break...)
- s = append(s, trailing_breaks...)
- }
- trailing_breaks = trailing_breaks[:0]
- leading_break = leading_break[:0]
- leading_blanks = false
- } else {
- s = append(s, whitespaces...)
- whitespaces = whitespaces[:0]
- }
- }
-
- // Copy the character.
- s = read(parser, s)
-
- end_mark = parser.mark
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
- }
-
- // Is it the end?
- if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
- break
- }
-
- // Consume blank characters.
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
-
- for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
- if is_blank(parser.buffer, parser.buffer_pos) {
-
- // Check for tab character that abuse indentation.
- if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
- yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
- start_mark, "found a tab character that violate indentation")
- return false
- }
-
- // Consume a space or a tab character.
- if !leading_blanks {
- whitespaces = read(parser, whitespaces)
- } else {
- skip(parser)
- }
- } else {
- if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
- return false
- }
-
- // Check if it is a first line break.
- if !leading_blanks {
- whitespaces = whitespaces[:0]
- leading_break = read_line(parser, leading_break)
- leading_blanks = true
- } else {
- trailing_breaks = read_line(parser, trailing_breaks)
- }
- }
- if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
- return false
- }
- }
-
- // Check indentation level.
- if parser.flow_level == 0 && parser.mark.column < indent {
- break
- }
- }
-
- // Create a token.
- *token = yaml_token_t{
- typ: yaml_SCALAR_TOKEN,
- start_mark: start_mark,
- end_mark: end_mark,
- value: s,
- style: yaml_PLAIN_SCALAR_STYLE,
- }
-
- // Note that we change the 'simple_key_allowed' flag.
- if leading_blanks {
- parser.simple_key_allowed = true
- }
- return true
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/sorter.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/sorter.go
deleted file mode 100644
index 5958822f9..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/sorter.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package yaml
-
-import (
- "reflect"
- "unicode"
-)
-
-type keyList []reflect.Value
-
-func (l keyList) Len() int { return len(l) }
-func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l keyList) Less(i, j int) bool {
- a := l[i]
- b := l[j]
- ak := a.Kind()
- bk := b.Kind()
- for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
- a = a.Elem()
- ak = a.Kind()
- }
- for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
- b = b.Elem()
- bk = b.Kind()
- }
- af, aok := keyFloat(a)
- bf, bok := keyFloat(b)
- if aok && bok {
- if af != bf {
- return af < bf
- }
- if ak != bk {
- return ak < bk
- }
- return numLess(a, b)
- }
- if ak != reflect.String || bk != reflect.String {
- return ak < bk
- }
- ar, br := []rune(a.String()), []rune(b.String())
- for i := 0; i < len(ar) && i < len(br); i++ {
- if ar[i] == br[i] {
- continue
- }
- al := unicode.IsLetter(ar[i])
- bl := unicode.IsLetter(br[i])
- if al && bl {
- return ar[i] < br[i]
- }
- if al || bl {
- return bl
- }
- var ai, bi int
- var an, bn int64
- for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
- an = an*10 + int64(ar[ai]-'0')
- }
- for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
- bn = bn*10 + int64(br[bi]-'0')
- }
- if an != bn {
- return an < bn
- }
- if ai != bi {
- return ai < bi
- }
- return ar[i] < br[i]
- }
- return len(ar) < len(br)
-}
-
-// keyFloat returns a float value for v if it is a number/bool
-// and whether it is a number/bool or not.
-func keyFloat(v reflect.Value) (f float64, ok bool) {
- switch v.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return float64(v.Int()), true
- case reflect.Float32, reflect.Float64:
- return v.Float(), true
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return float64(v.Uint()), true
- case reflect.Bool:
- if v.Bool() {
- return 1, true
- }
- return 0, true
- }
- return 0, false
-}
-
-// numLess returns whether a < b.
-// a and b must necessarily have the same kind.
-func numLess(a, b reflect.Value) bool {
- switch a.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return a.Int() < b.Int()
- case reflect.Float32, reflect.Float64:
- return a.Float() < b.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return a.Uint() < b.Uint()
- case reflect.Bool:
- return !a.Bool() && b.Bool()
- }
- panic("not a number")
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/writerc.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/writerc.go
deleted file mode 100644
index 190362f25..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/writerc.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package yaml
-
-// Set the writer error and return false.
-func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
- emitter.error = yaml_WRITER_ERROR
- emitter.problem = problem
- return false
-}
-
-// Flush the output buffer.
-func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
- if emitter.write_handler == nil {
- panic("write handler not set")
- }
-
- // Check if the buffer is empty.
- if emitter.buffer_pos == 0 {
- return true
- }
-
- // If the output encoding is UTF-8, we don't need to recode the buffer.
- if emitter.encoding == yaml_UTF8_ENCODING {
- if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
- return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
- }
- emitter.buffer_pos = 0
- return true
- }
-
- // Recode the buffer into the raw buffer.
- var low, high int
- if emitter.encoding == yaml_UTF16LE_ENCODING {
- low, high = 0, 1
- } else {
- high, low = 1, 0
- }
-
- pos := 0
- for pos < emitter.buffer_pos {
- // See the "reader.c" code for more details on UTF-8 encoding. Note
- // that we assume that the buffer contains a valid UTF-8 sequence.
-
- // Read the next UTF-8 character.
- octet := emitter.buffer[pos]
-
- var w int
- var value rune
- switch {
- case octet&0x80 == 0x00:
- w, value = 1, rune(octet&0x7F)
- case octet&0xE0 == 0xC0:
- w, value = 2, rune(octet&0x1F)
- case octet&0xF0 == 0xE0:
- w, value = 3, rune(octet&0x0F)
- case octet&0xF8 == 0xF0:
- w, value = 4, rune(octet&0x07)
- }
- for k := 1; k < w; k++ {
- octet = emitter.buffer[pos+k]
- value = (value << 6) + (rune(octet) & 0x3F)
- }
- pos += w
-
- // Write the character.
- if value < 0x10000 {
- var b [2]byte
- b[high] = byte(value >> 8)
- b[low] = byte(value & 0xFF)
- emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
- } else {
- // Write the character using a surrogate pair (check "reader.c").
- var b [4]byte
- value -= 0x10000
- b[high] = byte(0xD8 + (value >> 18))
- b[low] = byte((value >> 10) & 0xFF)
- b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
- b[low+2] = byte(value & 0xFF)
- emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
- }
- }
-
- // Write the raw buffer.
- if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
- return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
- }
- emitter.buffer_pos = 0
- emitter.raw_buffer = emitter.raw_buffer[:0]
- return true
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/yaml.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/yaml.go
deleted file mode 100644
index d133edf9d..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/yaml.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// Package yaml implements YAML support for the Go language.
-//
-// Source code and other details for the project are available at GitHub:
-//
-// https://github.com/go-yaml/yaml
-//
-package yaml
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strings"
- "sync"
-)
-
-// MapSlice encodes and decodes as a YAML map.
-// The order of keys is preserved when encoding and decoding.
-type MapSlice []MapItem
-
-// MapItem is an item in a MapSlice.
-type MapItem struct {
- Key, Value interface{}
-}
-
-// The Unmarshaler interface may be implemented by types to customize their
-// behavior when being unmarshaled from a YAML document. The UnmarshalYAML
-// method receives a function that may be called to unmarshal the original
-// YAML value into a field or variable. It is safe to call the unmarshal
-// function parameter more than once if necessary.
-type Unmarshaler interface {
- UnmarshalYAML(unmarshal func(interface{}) error) error
-}
-
-// The Marshaler interface may be implemented by types to customize their
-// behavior when being marshaled into a YAML document. The returned value
-// is marshaled in place of the original value implementing Marshaler.
-//
-// If an error is returned by MarshalYAML, the marshaling procedure stops
-// and returns with the provided error.
-type Marshaler interface {
- MarshalYAML() (interface{}, error)
-}
-
-// Unmarshal decodes the first document found within the in byte slice
-// and assigns decoded values into the out value.
-//
-// Maps and pointers (to a struct, string, int, etc) are accepted as out
-// values. If an internal pointer within a struct is not initialized,
-// the yaml package will initialize it if necessary for unmarshalling
-// the provided data. The out parameter must not be nil.
-//
-// The type of the decoded values should be compatible with the respective
-// values in out. If one or more values cannot be decoded due to a type
-// mismatches, decoding continues partially until the end of the YAML
-// content, and a *yaml.TypeError is returned with details for all
-// missed values.
-//
-// Struct fields are only unmarshalled if they are exported (have an
-// upper case first letter), and are unmarshalled using the field name
-// lowercased as the default key. Custom keys may be defined via the
-// "yaml" name in the field tag: the content preceding the first comma
-// is used as the key, and the following comma-separated options are
-// used to tweak the marshalling process (see Marshal).
-// Conflicting names result in a runtime error.
-//
-// For example:
-//
-// type T struct {
-// F int `yaml:"a,omitempty"`
-// B int
-// }
-// var t T
-// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
-//
-// See the documentation of Marshal for the format of tags and a list of
-// supported tag options.
-//
-func Unmarshal(in []byte, out interface{}) (err error) {
- defer handleErr(&err)
- d := newDecoder()
- p := newParser(in)
- defer p.destroy()
- node := p.parse()
- if node != nil {
- v := reflect.ValueOf(out)
- if v.Kind() == reflect.Ptr && !v.IsNil() {
- v = v.Elem()
- }
- d.unmarshal(node, v)
- }
- if len(d.terrors) > 0 {
- return &TypeError{d.terrors}
- }
- return nil
-}
-
-// Marshal serializes the value provided into a YAML document. The structure
-// of the generated document will reflect the structure of the value itself.
-// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
-//
-// Struct fields are only unmarshalled if they are exported (have an upper case
-// first letter), and are unmarshalled using the field name lowercased as the
-// default key. Custom keys may be defined via the "yaml" name in the field
-// tag: the content preceding the first comma is used as the key, and the
-// following comma-separated options are used to tweak the marshalling process.
-// Conflicting names result in a runtime error.
-//
-// The field tag format accepted is:
-//
-// `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`
-//
-// The following flags are currently supported:
-//
-// omitempty Only include the field if it's not set to the zero
-// value for the type or to empty slices or maps.
-// Does not apply to zero valued structs.
-//
-// flow Marshal using a flow style (useful for structs,
-// sequences and maps).
-//
-// inline Inline the field, which must be a struct or a map,
-// causing all of its fields or keys to be processed as if
-// they were part of the outer struct. For maps, keys must
-// not conflict with the yaml keys of other struct fields.
-//
-// In addition, if the key is "-", the field is ignored.
-//
-// For example:
-//
-// type T struct {
-// F int "a,omitempty"
-// B int
-// }
-// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
-// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
-//
-func Marshal(in interface{}) (out []byte, err error) {
- defer handleErr(&err)
- e := newEncoder()
- defer e.destroy()
- e.marshal("", reflect.ValueOf(in))
- e.finish()
- out = e.out
- return
-}
-
-func handleErr(err *error) {
- if v := recover(); v != nil {
- if e, ok := v.(yamlError); ok {
- *err = e.err
- } else {
- panic(v)
- }
- }
-}
-
-type yamlError struct {
- err error
-}
-
-func fail(err error) {
- panic(yamlError{err})
-}
-
-func failf(format string, args ...interface{}) {
- panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
-}
-
-// A TypeError is returned by Unmarshal when one or more fields in
-// the YAML document cannot be properly decoded into the requested
-// types. When this error is returned, the value is still
-// unmarshaled partially.
-type TypeError struct {
- Errors []string
-}
-
-func (e *TypeError) Error() string {
- return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
-}
-
-// --------------------------------------------------------------------------
-// Maintain a mapping of keys to structure field indexes
-
-// The code in this section was copied from mgo/bson.
-
-// structInfo holds details for the serialization of fields of
-// a given struct.
-type structInfo struct {
- FieldsMap map[string]fieldInfo
- FieldsList []fieldInfo
-
- // InlineMap is the number of the field in the struct that
- // contains an ,inline map, or -1 if there's none.
- InlineMap int
-}
-
-type fieldInfo struct {
- Key string
- Num int
- OmitEmpty bool
- Flow bool
-
- // Inline holds the field index if the field is part of an inlined struct.
- Inline []int
-}
-
-var structMap = make(map[reflect.Type]*structInfo)
-var fieldMapMutex sync.RWMutex
-
-func getStructInfo(st reflect.Type) (*structInfo, error) {
- fieldMapMutex.RLock()
- sinfo, found := structMap[st]
- fieldMapMutex.RUnlock()
- if found {
- return sinfo, nil
- }
-
- n := st.NumField()
- fieldsMap := make(map[string]fieldInfo)
- fieldsList := make([]fieldInfo, 0, n)
- inlineMap := -1
- for i := 0; i != n; i++ {
- field := st.Field(i)
- if field.PkgPath != "" {
- continue // Private field
- }
-
- info := fieldInfo{Num: i}
-
- tag := field.Tag.Get("yaml")
- if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
- tag = string(field.Tag)
- }
- if tag == "-" {
- continue
- }
-
- inline := false
- fields := strings.Split(tag, ",")
- if len(fields) > 1 {
- for _, flag := range fields[1:] {
- switch flag {
- case "omitempty":
- info.OmitEmpty = true
- case "flow":
- info.Flow = true
- case "inline":
- inline = true
- default:
- return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
- }
- }
- tag = fields[0]
- }
-
- if inline {
- switch field.Type.Kind() {
- case reflect.Map:
- if inlineMap >= 0 {
- return nil, errors.New("Multiple ,inline maps in struct " + st.String())
- }
- if field.Type.Key() != reflect.TypeOf("") {
- return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
- }
- inlineMap = info.Num
- case reflect.Struct:
- sinfo, err := getStructInfo(field.Type)
- if err != nil {
- return nil, err
- }
- for _, finfo := range sinfo.FieldsList {
- if _, found := fieldsMap[finfo.Key]; found {
- msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
- return nil, errors.New(msg)
- }
- if finfo.Inline == nil {
- finfo.Inline = []int{i, finfo.Num}
- } else {
- finfo.Inline = append([]int{i}, finfo.Inline...)
- }
- fieldsMap[finfo.Key] = finfo
- fieldsList = append(fieldsList, finfo)
- }
- default:
- //return nil, errors.New("Option ,inline needs a struct value or map field")
- return nil, errors.New("Option ,inline needs a struct value field")
- }
- continue
- }
-
- if tag != "" {
- info.Key = tag
- } else {
- info.Key = strings.ToLower(field.Name)
- }
-
- if _, found = fieldsMap[info.Key]; found {
- msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
- return nil, errors.New(msg)
- }
-
- fieldsList = append(fieldsList, info)
- fieldsMap[info.Key] = info
- }
-
- sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
-
- fieldMapMutex.Lock()
- structMap[st] = sinfo
- fieldMapMutex.Unlock()
- return sinfo, nil
-}
-
-func isZero(v reflect.Value) bool {
- switch v.Kind() {
- case reflect.String:
- return len(v.String()) == 0
- case reflect.Interface, reflect.Ptr:
- return v.IsNil()
- case reflect.Slice:
- return v.Len() == 0
- case reflect.Map:
- return v.Len() == 0
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Bool:
- return !v.Bool()
- case reflect.Struct:
- vt := v.Type()
- for i := v.NumField() - 1; i >= 0; i-- {
- if vt.Field(i).PkgPath != "" {
- continue // Private field
- }
- if !isZero(v.Field(i)) {
- return false
- }
- }
- return true
- }
- return false
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlh.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlh.go
deleted file mode 100644
index d60a6b6b0..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlh.go
+++ /dev/null
@@ -1,716 +0,0 @@
-package yaml
-
-import (
- "io"
-)
-
-// The version directive data.
-type yaml_version_directive_t struct {
- major int8 // The major version number.
- minor int8 // The minor version number.
-}
-
-// The tag directive data.
-type yaml_tag_directive_t struct {
- handle []byte // The tag handle.
- prefix []byte // The tag prefix.
-}
-
-type yaml_encoding_t int
-
-// The stream encoding.
-const (
- // Let the parser choose the encoding.
- yaml_ANY_ENCODING yaml_encoding_t = iota
-
- yaml_UTF8_ENCODING // The default UTF-8 encoding.
- yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
- yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
-)
-
-type yaml_break_t int
-
-// Line break types.
-const (
- // Let the parser choose the break type.
- yaml_ANY_BREAK yaml_break_t = iota
-
- yaml_CR_BREAK // Use CR for line breaks (Mac style).
- yaml_LN_BREAK // Use LN for line breaks (Unix style).
- yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
-)
-
-type yaml_error_type_t int
-
-// Many bad things could happen with the parser and emitter.
-const (
- // No error is produced.
- yaml_NO_ERROR yaml_error_type_t = iota
-
- yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory.
- yaml_READER_ERROR // Cannot read or decode the input stream.
- yaml_SCANNER_ERROR // Cannot scan the input stream.
- yaml_PARSER_ERROR // Cannot parse the input stream.
- yaml_COMPOSER_ERROR // Cannot compose a YAML document.
- yaml_WRITER_ERROR // Cannot write to the output stream.
- yaml_EMITTER_ERROR // Cannot emit a YAML stream.
-)
-
-// The pointer position.
-type yaml_mark_t struct {
- index int // The position index.
- line int // The position line.
- column int // The position column.
-}
-
-// Node Styles
-
-type yaml_style_t int8
-
-type yaml_scalar_style_t yaml_style_t
-
-// Scalar styles.
-const (
- // Let the emitter choose the style.
- yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
-
- yaml_PLAIN_SCALAR_STYLE // The plain scalar style.
- yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
- yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
- yaml_LITERAL_SCALAR_STYLE // The literal scalar style.
- yaml_FOLDED_SCALAR_STYLE // The folded scalar style.
-)
-
-type yaml_sequence_style_t yaml_style_t
-
-// Sequence styles.
-const (
- // Let the emitter choose the style.
- yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
-
- yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
- yaml_FLOW_SEQUENCE_STYLE // The flow sequence style.
-)
-
-type yaml_mapping_style_t yaml_style_t
-
-// Mapping styles.
-const (
- // Let the emitter choose the style.
- yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
-
- yaml_BLOCK_MAPPING_STYLE // The block mapping style.
- yaml_FLOW_MAPPING_STYLE // The flow mapping style.
-)
-
-// Tokens
-
-type yaml_token_type_t int
-
-// Token types.
-const (
- // An empty token.
- yaml_NO_TOKEN yaml_token_type_t = iota
-
- yaml_STREAM_START_TOKEN // A STREAM-START token.
- yaml_STREAM_END_TOKEN // A STREAM-END token.
-
- yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
- yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token.
- yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token.
- yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token.
-
- yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
- yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token.
- yaml_BLOCK_END_TOKEN // A BLOCK-END token.
-
- yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
- yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token.
- yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token.
- yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token.
-
- yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
- yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token.
- yaml_KEY_TOKEN // A KEY token.
- yaml_VALUE_TOKEN // A VALUE token.
-
- yaml_ALIAS_TOKEN // An ALIAS token.
- yaml_ANCHOR_TOKEN // An ANCHOR token.
- yaml_TAG_TOKEN // A TAG token.
- yaml_SCALAR_TOKEN // A SCALAR token.
-)
-
-func (tt yaml_token_type_t) String() string {
- switch tt {
- case yaml_NO_TOKEN:
- return "yaml_NO_TOKEN"
- case yaml_STREAM_START_TOKEN:
- return "yaml_STREAM_START_TOKEN"
- case yaml_STREAM_END_TOKEN:
- return "yaml_STREAM_END_TOKEN"
- case yaml_VERSION_DIRECTIVE_TOKEN:
- return "yaml_VERSION_DIRECTIVE_TOKEN"
- case yaml_TAG_DIRECTIVE_TOKEN:
- return "yaml_TAG_DIRECTIVE_TOKEN"
- case yaml_DOCUMENT_START_TOKEN:
- return "yaml_DOCUMENT_START_TOKEN"
- case yaml_DOCUMENT_END_TOKEN:
- return "yaml_DOCUMENT_END_TOKEN"
- case yaml_BLOCK_SEQUENCE_START_TOKEN:
- return "yaml_BLOCK_SEQUENCE_START_TOKEN"
- case yaml_BLOCK_MAPPING_START_TOKEN:
- return "yaml_BLOCK_MAPPING_START_TOKEN"
- case yaml_BLOCK_END_TOKEN:
- return "yaml_BLOCK_END_TOKEN"
- case yaml_FLOW_SEQUENCE_START_TOKEN:
- return "yaml_FLOW_SEQUENCE_START_TOKEN"
- case yaml_FLOW_SEQUENCE_END_TOKEN:
- return "yaml_FLOW_SEQUENCE_END_TOKEN"
- case yaml_FLOW_MAPPING_START_TOKEN:
- return "yaml_FLOW_MAPPING_START_TOKEN"
- case yaml_FLOW_MAPPING_END_TOKEN:
- return "yaml_FLOW_MAPPING_END_TOKEN"
- case yaml_BLOCK_ENTRY_TOKEN:
- return "yaml_BLOCK_ENTRY_TOKEN"
- case yaml_FLOW_ENTRY_TOKEN:
- return "yaml_FLOW_ENTRY_TOKEN"
- case yaml_KEY_TOKEN:
- return "yaml_KEY_TOKEN"
- case yaml_VALUE_TOKEN:
- return "yaml_VALUE_TOKEN"
- case yaml_ALIAS_TOKEN:
- return "yaml_ALIAS_TOKEN"
- case yaml_ANCHOR_TOKEN:
- return "yaml_ANCHOR_TOKEN"
- case yaml_TAG_TOKEN:
- return "yaml_TAG_TOKEN"
- case yaml_SCALAR_TOKEN:
- return "yaml_SCALAR_TOKEN"
- }
- return "<unknown token>"
-}
-
-// The token structure.
-type yaml_token_t struct {
- // The token type.
- typ yaml_token_type_t
-
- // The start/end of the token.
- start_mark, end_mark yaml_mark_t
-
- // The stream encoding (for yaml_STREAM_START_TOKEN).
- encoding yaml_encoding_t
-
- // The alias/anchor/scalar value or tag/tag directive handle
- // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
- value []byte
-
- // The tag suffix (for yaml_TAG_TOKEN).
- suffix []byte
-
- // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
- prefix []byte
-
- // The scalar style (for yaml_SCALAR_TOKEN).
- style yaml_scalar_style_t
-
- // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
- major, minor int8
-}
-
-// Events
-
-type yaml_event_type_t int8
-
-// Event types.
-const (
- // An empty event.
- yaml_NO_EVENT yaml_event_type_t = iota
-
- yaml_STREAM_START_EVENT // A STREAM-START event.
- yaml_STREAM_END_EVENT // A STREAM-END event.
- yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
- yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event.
- yaml_ALIAS_EVENT // An ALIAS event.
- yaml_SCALAR_EVENT // A SCALAR event.
- yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
- yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event.
- yaml_MAPPING_START_EVENT // A MAPPING-START event.
- yaml_MAPPING_END_EVENT // A MAPPING-END event.
-)
-
-// The event structure.
-type yaml_event_t struct {
-
- // The event type.
- typ yaml_event_type_t
-
- // The start and end of the event.
- start_mark, end_mark yaml_mark_t
-
- // The document encoding (for yaml_STREAM_START_EVENT).
- encoding yaml_encoding_t
-
- // The version directive (for yaml_DOCUMENT_START_EVENT).
- version_directive *yaml_version_directive_t
-
- // The list of tag directives (for yaml_DOCUMENT_START_EVENT).
- tag_directives []yaml_tag_directive_t
-
- // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
- anchor []byte
-
- // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
- tag []byte
-
- // The scalar value (for yaml_SCALAR_EVENT).
- value []byte
-
- // Is the document start/end indicator implicit, or the tag optional?
- // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
- implicit bool
-
- // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
- quoted_implicit bool
-
- // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
- style yaml_style_t
-}
-
-func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) }
-func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
-func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) }
-
-// Nodes
-
-const (
- yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null.
- yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false.
- yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values.
- yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values.
- yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values.
- yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
-
- yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
- yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
-
- // Not in original libyaml.
- yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
- yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
-
- yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
- yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
- yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
-)
-
-type yaml_node_type_t int
-
-// Node types.
-const (
- // An empty node.
- yaml_NO_NODE yaml_node_type_t = iota
-
- yaml_SCALAR_NODE // A scalar node.
- yaml_SEQUENCE_NODE // A sequence node.
- yaml_MAPPING_NODE // A mapping node.
-)
-
-// An element of a sequence node.
-type yaml_node_item_t int
-
-// An element of a mapping node.
-type yaml_node_pair_t struct {
- key int // The key of the element.
- value int // The value of the element.
-}
-
-// The node structure.
-type yaml_node_t struct {
- typ yaml_node_type_t // The node type.
- tag []byte // The node tag.
-
- // The node data.
-
- // The scalar parameters (for yaml_SCALAR_NODE).
- scalar struct {
- value []byte // The scalar value.
- length int // The length of the scalar value.
- style yaml_scalar_style_t // The scalar style.
- }
-
- // The sequence parameters (for YAML_SEQUENCE_NODE).
- sequence struct {
- items_data []yaml_node_item_t // The stack of sequence items.
- style yaml_sequence_style_t // The sequence style.
- }
-
- // The mapping parameters (for yaml_MAPPING_NODE).
- mapping struct {
- pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value).
- pairs_start *yaml_node_pair_t // The beginning of the stack.
- pairs_end *yaml_node_pair_t // The end of the stack.
- pairs_top *yaml_node_pair_t // The top of the stack.
- style yaml_mapping_style_t // The mapping style.
- }
-
- start_mark yaml_mark_t // The beginning of the node.
- end_mark yaml_mark_t // The end of the node.
-
-}
-
-// The document structure.
-type yaml_document_t struct {
-
- // The document nodes.
- nodes []yaml_node_t
-
- // The version directive.
- version_directive *yaml_version_directive_t
-
- // The list of tag directives.
- tag_directives_data []yaml_tag_directive_t
- tag_directives_start int // The beginning of the tag directives list.
- tag_directives_end int // The end of the tag directives list.
-
- start_implicit int // Is the document start indicator implicit?
- end_implicit int // Is the document end indicator implicit?
-
- // The start/end of the document.
- start_mark, end_mark yaml_mark_t
-}
-
-// The prototype of a read handler.
-//
-// The read handler is called when the parser needs to read more bytes from the
-// source. The handler should write not more than size bytes to the buffer.
-// The number of written bytes should be set to the size_read variable.
-//
-// [in,out] data A pointer to an application data specified by
-// yaml_parser_set_input().
-// [out] buffer The buffer to write the data from the source.
-// [in] size The size of the buffer.
-// [out] size_read The actual number of bytes read from the source.
-//
-// On success, the handler should return 1. If the handler failed,
-// the returned value should be 0. On EOF, the handler should set the
-// size_read to 0 and return 1.
-type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
-
-// This structure holds information about a potential simple key.
-type yaml_simple_key_t struct {
- possible bool // Is a simple key possible?
- required bool // Is a simple key required?
- token_number int // The number of the token.
- mark yaml_mark_t // The position mark.
-}
-
-// The states of the parser.
-type yaml_parser_state_t int
-
-const (
- yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
-
- yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document.
- yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START.
- yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document.
- yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END.
- yaml_PARSE_BLOCK_NODE_STATE // Expect a block node.
- yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
- yaml_PARSE_FLOW_NODE_STATE // Expect a flow node.
- yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence.
- yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence.
- yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence.
- yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
- yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key.
- yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value.
- yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence.
- yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence.
- yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping.
- yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
- yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry.
- yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
- yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
- yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
- yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping.
- yaml_PARSE_END_STATE // Expect nothing.
-)
-
-func (ps yaml_parser_state_t) String() string {
- switch ps {
- case yaml_PARSE_STREAM_START_STATE:
- return "yaml_PARSE_STREAM_START_STATE"
- case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
- return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
- case yaml_PARSE_DOCUMENT_START_STATE:
- return "yaml_PARSE_DOCUMENT_START_STATE"
- case yaml_PARSE_DOCUMENT_CONTENT_STATE:
- return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
- case yaml_PARSE_DOCUMENT_END_STATE:
- return "yaml_PARSE_DOCUMENT_END_STATE"
- case yaml_PARSE_BLOCK_NODE_STATE:
- return "yaml_PARSE_BLOCK_NODE_STATE"
- case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
- return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
- case yaml_PARSE_FLOW_NODE_STATE:
- return "yaml_PARSE_FLOW_NODE_STATE"
- case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
- return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
- case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
- return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
- case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
- return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
- case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
- return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
- case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
- return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
- case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
- return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
- case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
- return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
- return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
- return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
- return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
- case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
- return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
- case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
- return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
- case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
- return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
- case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
- return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
- case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
- return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
- case yaml_PARSE_END_STATE:
- return "yaml_PARSE_END_STATE"
- }
- return "<unknown parser state>"
-}
-
-// This structure holds aliases data.
-type yaml_alias_data_t struct {
- anchor []byte // The anchor.
- index int // The node id.
- mark yaml_mark_t // The anchor mark.
-}
-
-// The parser structure.
-//
-// All members are internal. Manage the structure using the
-// yaml_parser_ family of functions.
-type yaml_parser_t struct {
-
- // Error handling
-
- error yaml_error_type_t // Error type.
-
- problem string // Error description.
-
- // The byte about which the problem occured.
- problem_offset int
- problem_value int
- problem_mark yaml_mark_t
-
- // The error context.
- context string
- context_mark yaml_mark_t
-
- // Reader stuff
-
- read_handler yaml_read_handler_t // Read handler.
-
- input_file io.Reader // File input data.
- input []byte // String input data.
- input_pos int
-
- eof bool // EOF flag
-
- buffer []byte // The working buffer.
- buffer_pos int // The current position of the buffer.
-
- unread int // The number of unread characters in the buffer.
-
- raw_buffer []byte // The raw buffer.
- raw_buffer_pos int // The current position of the buffer.
-
- encoding yaml_encoding_t // The input encoding.
-
- offset int // The offset of the current position (in bytes).
- mark yaml_mark_t // The mark of the current position.
-
- // Scanner stuff
-
- stream_start_produced bool // Have we started to scan the input stream?
- stream_end_produced bool // Have we reached the end of the input stream?
-
- flow_level int // The number of unclosed '[' and '{' indicators.
-
- tokens []yaml_token_t // The tokens queue.
- tokens_head int // The head of the tokens queue.
- tokens_parsed int // The number of tokens fetched from the queue.
- token_available bool // Does the tokens queue contain a token ready for dequeueing.
-
- indent int // The current indentation level.
- indents []int // The indentation levels stack.
-
- simple_key_allowed bool // May a simple key occur at the current position?
- simple_keys []yaml_simple_key_t // The stack of simple keys.
-
- // Parser stuff
-
- state yaml_parser_state_t // The current parser state.
- states []yaml_parser_state_t // The parser states stack.
- marks []yaml_mark_t // The stack of marks.
- tag_directives []yaml_tag_directive_t // The list of TAG directives.
-
- // Dumper stuff
-
- aliases []yaml_alias_data_t // The alias data.
-
- document *yaml_document_t // The currently parsed document.
-}
-
-// Emitter Definitions
-
-// The prototype of a write handler.
-//
-// The write handler is called when the emitter needs to flush the accumulated
-// characters to the output. The handler should write @a size bytes of the
-// @a buffer to the output.
-//
-// @param[in,out] data A pointer to an application data specified by
-// yaml_emitter_set_output().
-// @param[in] buffer The buffer with bytes to be written.
-// @param[in] size The size of the buffer.
-//
-// @returns On success, the handler should return @c 1. If the handler failed,
-// the returned value should be @c 0.
-//
-type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
-
-type yaml_emitter_state_t int
-
-// The emitter states.
-const (
- // Expect STREAM-START.
- yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
-
- yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
- yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
- yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
- yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
- yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
- yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
- yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
- yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
- yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
- yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
- yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
- yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
- yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
- yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
- yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
- yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
- yaml_EMIT_END_STATE // Expect nothing.
-)
-
-// The emitter structure.
-//
-// All members are internal. Manage the structure using the @c yaml_emitter_
-// family of functions.
-type yaml_emitter_t struct {
-
- // Error handling
-
- error yaml_error_type_t // Error type.
- problem string // Error description.
-
- // Writer stuff
-
- write_handler yaml_write_handler_t // Write handler.
-
- output_buffer *[]byte // String output data.
- output_file io.Writer // File output data.
-
- buffer []byte // The working buffer.
- buffer_pos int // The current position of the buffer.
-
- raw_buffer []byte // The raw buffer.
- raw_buffer_pos int // The current position of the buffer.
-
- encoding yaml_encoding_t // The stream encoding.
-
- // Emitter stuff
-
- canonical bool // If the output is in the canonical style?
- best_indent int // The number of indentation spaces.
- best_width int // The preferred width of the output lines.
- unicode bool // Allow unescaped non-ASCII characters?
- line_break yaml_break_t // The preferred line break.
-
- state yaml_emitter_state_t // The current emitter state.
- states []yaml_emitter_state_t // The stack of states.
-
- events []yaml_event_t // The event queue.
- events_head int // The head of the event queue.
-
- indents []int // The stack of indentation levels.
-
- tag_directives []yaml_tag_directive_t // The list of tag directives.
-
- indent int // The current indentation level.
-
- flow_level int // The current flow level.
-
- root_context bool // Is it the document root context?
- sequence_context bool // Is it a sequence context?
- mapping_context bool // Is it a mapping context?
- simple_key_context bool // Is it a simple mapping key context?
-
- line int // The current line.
- column int // The current column.
- whitespace bool // If the last character was a whitespace?
- indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
- open_ended bool // If an explicit document end is required?
-
- // Anchor analysis.
- anchor_data struct {
- anchor []byte // The anchor value.
- alias bool // Is it an alias?
- }
-
- // Tag analysis.
- tag_data struct {
- handle []byte // The tag handle.
- suffix []byte // The tag suffix.
- }
-
- // Scalar analysis.
- scalar_data struct {
- value []byte // The scalar value.
- multiline bool // Does the scalar contain line breaks?
- flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
- block_plain_allowed bool // Can the scalar be expressed in the block plain style?
- single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
- block_allowed bool // Can the scalar be expressed in the literal or folded styles?
- style yaml_scalar_style_t // The output style.
- }
-
- // Dumper stuff
-
- opened bool // If the stream was already opened?
- closed bool // If the stream was already closed?
-
- // The information associated with the document nodes.
- anchors *struct {
- references int // The number of references.
- anchor int // The anchor id.
- serialized bool // If the node has been emitted?
- }
-
- last_anchor_id int // The last assigned anchor id.
-
- document *yaml_document_t // The currently emitted document.
-}
diff --git a/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlprivateh.go b/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlprivateh.go
deleted file mode 100644
index 8110ce3c3..000000000
--- a/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlprivateh.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package yaml
-
-const (
- // The size of the input raw buffer.
- input_raw_buffer_size = 512
-
- // The size of the input buffer.
- // It should be possible to decode the whole raw buffer.
- input_buffer_size = input_raw_buffer_size * 3
-
- // The size of the output buffer.
- output_buffer_size = 128
-
- // The size of the output raw buffer.
- // It should be possible to encode the whole output buffer.
- output_raw_buffer_size = (output_buffer_size*2 + 2)
-
- // The size of other stacks and queues.
- initial_stack_size = 16
- initial_queue_size = 16
- initial_string_size = 16
-)
-
-// Check if the character at the specified position is an alphabetical
-// character, a digit, '_', or '-'.
-func is_alpha(b []byte, i int) bool {
- return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
-}
-
-// Check if the character at the specified position is a digit.
-func is_digit(b []byte, i int) bool {
- return b[i] >= '0' && b[i] <= '9'
-}
-
-// Get the value of a digit.
-func as_digit(b []byte, i int) int {
- return int(b[i]) - '0'
-}
-
-// Check if the character at the specified position is a hex-digit.
-func is_hex(b []byte, i int) bool {
- return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
-}
-
-// Get the value of a hex-digit.
-func as_hex(b []byte, i int) int {
- bi := b[i]
- if bi >= 'A' && bi <= 'F' {
- return int(bi) - 'A' + 10
- }
- if bi >= 'a' && bi <= 'f' {
- return int(bi) - 'a' + 10
- }
- return int(bi) - '0'
-}
-
-// Check if the character is ASCII.
-func is_ascii(b []byte, i int) bool {
- return b[i] <= 0x7F
-}
-
-// Check if the character at the start of the buffer can be printed unescaped.
-func is_printable(b []byte, i int) bool {
- return ((b[i] == 0x0A) || // . == #x0A
- (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
- (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
- (b[i] > 0xC2 && b[i] < 0xED) ||
- (b[i] == 0xED && b[i+1] < 0xA0) ||
- (b[i] == 0xEE) ||
- (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
- !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
- !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
-}
-
-// Check if the character at the specified position is NUL.
-func is_z(b []byte, i int) bool {
- return b[i] == 0x00
-}
-
-// Check if the beginning of the buffer is a BOM.
-func is_bom(b []byte, i int) bool {
- return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
-}
-
-// Check if the character at the specified position is space.
-func is_space(b []byte, i int) bool {
- return b[i] == ' '
-}
-
-// Check if the character at the specified position is tab.
-func is_tab(b []byte, i int) bool {
- return b[i] == '\t'
-}
-
-// Check if the character at the specified position is blank (space or tab).
-func is_blank(b []byte, i int) bool {
- //return is_space(b, i) || is_tab(b, i)
- return b[i] == ' ' || b[i] == '\t'
-}
-
-// Check if the character at the specified position is a line break.
-func is_break(b []byte, i int) bool {
- return (b[i] == '\r' || // CR (#xD)
- b[i] == '\n' || // LF (#xA)
- b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
-}
-
-func is_crlf(b []byte, i int) bool {
- return b[i] == '\r' && b[i+1] == '\n'
-}
-
-// Check if the character is a line break or NUL.
-func is_breakz(b []byte, i int) bool {
- //return is_break(b, i) || is_z(b, i)
- return ( // is_break:
- b[i] == '\r' || // CR (#xD)
- b[i] == '\n' || // LF (#xA)
- b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
- // is_z:
- b[i] == 0)
-}
-
-// Check if the character is a line break, space, or NUL.
-func is_spacez(b []byte, i int) bool {
- //return is_space(b, i) || is_breakz(b, i)
- return ( // is_space:
- b[i] == ' ' ||
- // is_breakz:
- b[i] == '\r' || // CR (#xD)
- b[i] == '\n' || // LF (#xA)
- b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
- b[i] == 0)
-}
-
-// Check if the character is a line break, space, tab, or NUL.
-func is_blankz(b []byte, i int) bool {
- //return is_blank(b, i) || is_breakz(b, i)
- return ( // is_blank:
- b[i] == ' ' || b[i] == '\t' ||
- // is_breakz:
- b[i] == '\r' || // CR (#xD)
- b[i] == '\n' || // LF (#xA)
- b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
- b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
- b[i] == 0)
-}
-
-// Determine the width of the character.
-func width(b byte) int {
- // Don't replace these by a switch without first
- // confirming that it is being inlined.
- if b&0x80 == 0x00 {
- return 1
- }
- if b&0xE0 == 0xC0 {
- return 2
- }
- if b&0xF0 == 0xE0 {
- return 3
- }
- if b&0xF8 == 0xF0 {
- return 4
- }
- return 0
-
-}